第一种方式
- 注册ServerEndpointExporter
@Configuration
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}
- 配置serverpoint
package com.yeyoo.websocket.websocket;
import org.springframework.stereotype.Component;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;
/**
* Created by @163.com on 2020-11-02.
*/
@ServerEndpoint(value = "/connectWebSocket/{userId}")
@Component
public class WebServicePoint {
private static ConcurrentHashMap<String, WebServicePoint> user = new ConcurrentHashMap<String, WebServicePoint>();
private Session session;
@OnOpen
public void onOpen(Session session, @PathParam("userId") String userId) {
String id = session.getId();
this.session = session;
user.put("1", this);
System.out.println("连接成功");
}
@OnClose
public void onClose(Session session) {
System.out.println("连接断开");
}
/**
*
* @param session
* @param error
*/
@OnError
public void onError(Session session, Throwable error) {
error.printStackTrace();
}
@OnMessage
public void onMessage(String message) {
System.out.println(message);
}
public void sendMessage(String message) throws IOException {
this.session.getBasicRemote().sendText(message);
}
public void sendMessagess(String message) {
WebServicePoint webServicePoint = user.get("1");
try {
webServicePoint.sendMessage(message);
} catch (IOException e) {
e.printStackTrace();
}
}
}
- 前端连接
var websocket = null;
$(function () {
if ('WebSocket' in window) {
websocket = new WebSocket("ws://localhost:8088/connectWebSocket/{userId}" );
// websocket = new WebSocket("ws://localhost:8088/websocket.do" );
websocket.onmessage = function(e) {
console.log(e.data);
}
} else {
alert('当前浏览器 Not support websocket')
}
if (websocket.readyState = WebSocket.CONNECTING) {
console.log("websocket正在连接!")
}
websocket.onopen = function () {
if (websocket.readyState = WebSocket.CONNECTING) {
console.log("websocket正在连接!")
}
if (websocket.readyState = WebSocket.OPEN) {
console.log("websocket已经打开!")
}
}
websocket.onmessage = function(e) {
console.log(e.data);
websocket.send("123456")
}
websocket.onclose = function () {
if(websocket.readyState == WebSocket.CLOSED){
console.log('连接已关闭')
}
alert("连接报错")
}
websocket.onerror = function () {
alert("连接报错")
}
})
function zhengce() {
websocket.send("7878877")
}
第二种方式
1.配置TestWebSocketHandler
package com.yeyoo.websocket.handler;
import org.springframework.stereotype.Service;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
/**
* Created by SunJianKang@163.com on 2020-11-03.
*/
@Service
public class TestWebSocketHandler extends TextWebSocketHandler {
public static final Map users = new HashMap<String, WebSocketSession>();
/**
* 连接成功时候 调用
*/
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
users.put("userId", session);
// 这块会实现自己业务,比如,当用户登录后,会把离线消息推送给用户
// TextMessage returnMessage = new TextMessage("你将收到的离线");
// session.sendMessage(returnMessage);
super.afterConnectionEstablished(session);
}
/**
* js 调用websocket.send 时候触发
* @param session
* @param message
* @throws Exception
*/
@Override
protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
super.handleTextMessage(session, message);
}
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
users.remove("userId");
super.afterConnectionClosed(session, status);
}
@Override
public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
if (session.isOpen()) {
session.close();
}
users.remove(session);
}
/**
* 给某个用户发送消息
*
* @param userName
* @param message
*/
public void sendMessageToUser(String userName, TextMessage message) {
System.out.println(userName + "111111111111111111111111111" + message);
WebSocketSession user = (WebSocketSession) users.get("userId");
try {
if (user.isOpen()) {
user.sendMessage(message);
}
} catch (IOException e) {
e.printStackTrace();
}
/* for (WebSocketSession user : users) {
if (user.getAttributes().get(WEBSOCKET_USERNAME).equals(userName)) {
try {
if (user.isOpen()) {
user.sendMessage(message);
}
} catch (IOException e) {
e.printStackTrace();
}
break;
}
}*/
}
/**
* 给所有在线用户发送消息
*
* @param message
*/
public void sendMessageToUsers(TextMessage message) {
/* for (WebSocketSession user : users) {
try {
if (user.isOpen()) {
user.sendMessage(message);
}
} catch (IOException e) {
e.printStackTrace();
}
}*/
}
// 自定义方法
}
- 配置拦截器 Interceptor
package com.yeyoo.websocket.handler;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor;
import java.util.Map;
/**
* WebSocket拦截器
*
* @author jinyifeng5969@163.com
* @since 2018年12月22日 下午3:55:16
* @version v1.0.0
*
*/
public class YeyooWebSocketInterceptor extends HttpSessionHandshakeInterceptor {
@Override
public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler handler,
Exception ex) {
super.afterHandshake(request, response, handler, ex);
}
@Override
public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler handler,
Map<String, Object> attributes) throws Exception {
/*if (request instanceof ServletServerHttpRequest) {
ServletServerHttpRequest servlet = (ServletServerHttpRequest) request;
HttpSession session = servlet.getServletRequest().getSession(false);
if (null != session) {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
attributes.put(Constant.$USERNAME, ObjectUtils.defaultIfNull(authentication.getName(), "default-system"));
}
}*/
return super.beforeHandshake(request, response, handler, attributes);
}
}
- 在TestWebSockectConfig 中注册 handler
package com.yeyoo.websocket.config;
import com.yeyoo.websocket.handler.TestWebSocketHandler;
import com.yeyoo.websocket.handler.YeyooWebSocketInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
import javax.annotation.Resource;
/**
* Created by SunJianKang@163.com on 2020-11-04.
*
* 实现WebSocketConfigurer接口,重写registerWebSocketHandlers方法,
* 这是一个核心实现方法,配置websocket入口,允许访问的域、注册Handler、SockJs支持和拦截器。
*
*
*
*/
@Configuration
@EnableWebSocket
public class TestWebSockectConfig implements WebSocketConfigurer {
@Resource
private TestWebSocketHandler testWebSocketHandler;
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
/**
* addInterceptors,顾名思义就是为handler添加拦截器,可以在调用handler前后加入我们自己的逻辑代码。
*/
registry.addHandler(testWebSocketHandler, "/websocket.do")
.setAllowedOrigins("*")
.addInterceptors(new YeyooWebSocketInterceptor());
registry.addHandler(testWebSocketHandler, "/websocket.do")
.setAllowedOrigins("*")
.addInterceptors(new YeyooWebSocketInterceptor())
.withSockJS();
}
}
ok ! 这只是简单的通过websocket连接前后端, 具体的业务还要根据实际业务来定。