SpringBoot接入WebSocket详解(含源码)
1.实际效果
2.添加一个WebSocketConfig
package com.llltony.springboot.config; import org.springframework.context.annotation.Bean; import org.springframework.stereotype.Component; import org.springframework.web.socket.server.standard.ServerEndpointExporter; @Component public class WebSocketConfig { /** * ServerEndpointExporter 作用 * * 这个Bean会自动注册使用@ServerEndpoint注解声明的websocket endpoint * * @return */ @Bean public ServerEndpointExporter serverEndpointExporter() { return new ServerEndpointExporter(); } }
3.添加WebSocket类
package com.llltony.springboot.socket; import com.alibaba.fastjson.JSONObject; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import javax.websocket.OnClose; import javax.websocket.OnMessage; import javax.websocket.OnOpen; import javax.websocket.Session; import javax.websocket.server.PathParam; import javax.websocket.server.ServerEndpoint; import java.util.concurrent.ConcurrentHashMap; /** * @ServerEndpoint 这个注解有什么作用? ** 这个注解用于标识作用在类上,它的主要功能是把当前类标识成一个WebSocket的服务端 * 注解的值用户客户端连接访问的URL地址
*/ @Slf4j @Component @ServerEndpoint("/websocket/{name}") public class WebSocket { /** * 与某个客户端的连接对话,需要通过它来给客户端发送消息 */ private Session session; /** * 标识当前连接客户端的用户名 */ private String name; /** * 用于存所有的连接服务的客户端,这个对象存储是安全的 */ private static ConcurrentHashMapwebSocketSet = new ConcurrentHashMap<>(); @OnOpen public void OnOpen(Session session, @PathParam(value = "name") String name) { this.session = session; this.name = name; // name是用来表示唯一客户端,如果需要指定发送,需要指定发送通过name来区分 webSocketSet.put(name, this); log.info(name+"[WebSocket] 连接成功,当前连接人数为:={}", webSocketSet.size()); } @OnClose public void OnClose() { webSocketSet.remove(this.name); log.info(name+"[WebSocket] 退出成功,当前连接人数为:={}", webSocketSet.size()); } @OnMessage public void OnMessage(String message) { log.info("[WebSocket] 收到消息:{}", message); //根据用户名判断知道发送 JSONObject json = JSONObject.parseObject(message); String name=json.get("username").toString(); String content=json.get("content").toString(); if (!name.equals("") && name!= null) { AppointSending(name, content); } else { GroupSending(message); } } /** * 群发 * * @param message */ public void GroupSending(String message) { for (String name : webSocketSet.keySet()) { try { webSocketSet.get(name).session.getBasicRemote().sendText(message); } catch (Exception e) { e.printStackTrace(); } } } /** * 指定发送 * * @param name * @param message */ public void AppointSending(String name, String message) { try { webSocketSet.get(name).session.getBasicRemote().sendText(message); } catch (Exception e) { e.printStackTrace(); } } }
4.添加pom依赖
<dependency> <groupId>org.springframework.bootgroupId> <artifactId>spring-boot-starter-websocketartifactId> dependency> <dependency> <groupId>org.projectlombokgroupId> <artifactId>lombokartifactId> dependency> <dependency> <groupId>com.alibabagroupId> <artifactId>fastjsonartifactId> <version>1.2.47version> dependency>
5.添加html页面进行调用测试
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>websocket_Testtitle>
<script src="https://cdn.bootcss.com/jquery/3.0.0/jquery.min.js">script>
<meta content="no-cache" http-equiv="pragma">
<meta content="no-cache" http-equiv="cache-control">
<meta content="0" http-equiv="expires">
<meta content="keyword1,keyword2,keyword3" http-equiv="keywords">
<meta content="This is my page" http-equiv="description">
head>
<body>
<div>
<h3>testing...h3>
<div id="msgtext">
div>
<div>
<input id="username" name="username" type="text" placeholder="请输入用户名"/>
<button onclick="connectWebSocket();">连接WebSocketbutton>
<br>
<input id="msg" name="msg" type="text" placeholder="请输入发生信息"/>
<button onclick="sendmsg();">发送button>
div>
div>
body>
<script type="text/javascript">
var ws;
function connectWebSocket(){
if('WebSocket' in window){
var url="ws://localhost:8080/websocket/";
var username=$('#username').val();
if(username=="" || username==null){
alert("请输入用户名");
return;
}else{
url=url+username;
}
ws = new WebSocket(url);
}else{
alert("不支持 websocket");
}
ws.onopen = function(evt){
//alert("op");
}
ws.onclose =function(evt){
alert("close");
}
ws.onmessage = function(evt){
var msg = evt.data;
if("[object Blob]" != msg){
var msgdiv = document.getElementById("msgtext");
var span = document.createElement("span");
span.innerHTML = msg+"
";
msgdiv.appendChild(span);
}else{
var msgdiv = document.getElementById("msgtext");
var span = document.createElement("span");
var br = document.createElement("br");
var can = document.createElement("canvas");
var context = can.getContext("2d");
var image = new Image();
image.onload = function () {
//image.height
context.clearRect(0, 0, can.width, can.height);
context.drawImage(image, 0, 0, can.width, can.height);
}
image.src = URL.createObjectURL(msg);
span.appendChild(can);
span.appendChild(br);
msgdiv.appendChild(span);
}
}
ws.onerror = function(evt){
alert("error");
}
}
function sendmsg(){
var message={};
message.content="("+new Date().toLocaleTimeString()+")
"+document.getElementById("msg").value;
message.username=$('#username').val();
ws.send(JSON.stringify(message));
}
script>
html>
6.后端代码里的调用websocket发送消息
7.源码:https://github.com/CodingPandaLLL/tsl.git(在dev_webSocket分支中)