第一次写博客,备份下代码,顺便给需要的同学看看,
网上也有很多Java整合webSocket的例子,大多自己写个类继承 WebSocketConfigurer ,
直接使用注解的比较少,我也看了很多写的运行有问题,要么代码关键部分缺少,想着自己弄一个好了,这个版本在网上某些大佬的基础上实现的,基础代码重复写没意义。
1.加入websocket依赖包
<!-- WebSocket --> <dependency> <groupId>org.springframework</groupId>
<artifactId>spring-websocket</artifactId> <version>${spring.version}</version>
</dependency> <dependency> <groupId>org.springframework</groupId>
<artifactId>spring-messaging</artifactId> <version>${spring.version}</version>
</dependency>
2.在Namespaces中勾选websocket
3.配置请求地址
<!-- 配置webSockte --> <!-- 实现webscoket接口 --> <bean id="wsHandler"
class="com.spd.sw.websocket.MyMessageHandler"/> <websocket:handlers
allowed-origins="*"> <!-- 前端握手请求地址 --> <websocket:mapping path="/socketServer"
handler="wsHandler"/> <websocket:handshake-interceptors> <bean
class="com.spd.sw.websocket.WebSocketInterceptor"/>
</websocket:handshake-interceptors> </websocket:handlers>
4.拦截器配置
public class WebSocketInterceptor extends HttpSessionHandshakeInterceptor {
/** * TODO 描述该方法的实现功能. * @see
org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor#beforeHandshake(org.springframework.http.server.ServerHttpRequest,
org.springframework.http.server.ServerHttpResponse,
org.springframework.web.socket.WebSocketHandler, java.util.Map) */ @Override
public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse
response, WebSocketHandler wsHandler, Map<String, Object> attributes) throws
Exception { if(request instanceof ServletServerHttpRequest){
ServletServerHttpRequest serverHttpRequest = (ServletServerHttpRequest)request;
//获取参数 String userId = serverHttpRequest
.getServletRequest().getParameter("userId");
attributes.put(MyMessageHandler.USER_KEY, userId); } return true; } }
5.socket用户及msg
/** * ClassName: MyMessageHandler * Function: 实现webscoket接口 * @version */
@Service public class MyMessageHandler implements WebSocketHandler { //用户
public static final String USER_KEY = "socket_user"; /** *
userMap:存储用户连接webscoket信息 * @since JDK 1.7 */ private final static int
size=300;//用户数量 private final static Map<String, WebSocketSession> userMap;
static { userMap = new ConcurrentHashMap<String,WebSocketSession>(size); } /**
* 关闭websocket时调用该方法 * @see
org.springframework.web.socket.WebSocketHandler#afterConnectionClosed(org.springframework.web.socket.WebSocketSession,
org.springframework.web.socket.CloseStatus) */ @Override public void
afterConnectionClosed(WebSocketSession session, CloseStatus status) throws
Exception { String userId = this.getUserId(session);
if(StringUtils.isNoneBlank(userId)){ userMap.remove(userId);
System.err.println(userId +"用户已成功关闭会话"); }else{
System.err.println("关闭时,获取用户id为空"); } } /** * 建立websocket连接时调用该方法 * @see
org.springframework.web.socket.WebSocketHandler#afterConnectionEstablished(org.springframework.web.socket.WebSocketSession)
*/ @Override public void afterConnectionEstablished(WebSocketSession session)
throws Exception { String userId = this.getUserId(session);
if(StringUtils.isNoneBlank(userId)){ userMap.put(userId, session);
//session.sendMessage(new TextMessage("用户"+userId+"建立WebSocket连接成功!"));
//给所有用户发送消息 } } /** * 客户端调用websocket.send时候,会调用该方法,进行数据通信 * @see
org.springframework.web.socket.WebSocketHandler#handleMessage(org.springframework.web.socket.WebSocketSession,
org.springframework.web.socket.WebSocketMessage) */ @Override public void
handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws
Exception { String msg = message.toString(); String userId =
this.getUserId(session); System.err.println("该"+userId+"用户发送的消息是:"+msg);
message = new TextMessage("服务端已经接收到消息,msg="+msg); session.sendMessage(message);
} /** * 传输过程出现异常时,调用该方法 * @see
org.springframework.web.socket.WebSocketHandler#handleTransportError(org.springframework.web.socket.WebSocketSession,
java.lang.Throwable) */ @Override public void
handleTransportError(WebSocketSession session, Throwable e) throws Exception {
WebSocketMessage<String> message = new TextMessage("异常信息:"+e.getMessage());
session.sendMessage(message); } /** * * @see
org.springframework.web.socket.WebSocketHandler#supportsPartialMessages() */
@Override public boolean supportsPartialMessages() { return false; } /** *
sendMessageToUser:发给指定用户 * * @param userId * @param contents * @since JDK 1.7
*/ public void sendMessageToUser(String userId,String contents) {
WebSocketSession session = userMap.get(userId); if(session !=null &&
session.isOpen()) { try { TextMessage message = new TextMessage(contents);
session.sendMessage(message); } catch (IOException e) { e.printStackTrace(); }
} } /** * sendMessageToAllUsers:发给所有的用户 * * @param contents * @since JDK 1.7 */
public void sendMessageToAllUsers(String contents) { Set<String> userIds =
userMap.keySet(); for(String userId: userIds) { this.sendMessageToUser(userId,
contents); } } /** * getUserId:获取用户id * * * @param session * @return * @since
JDK 1.7 */ private String getUserId(WebSocketSession session){ try { String
userId = (String)session.getAttributes().get(USER_KEY); return userId; } catch
(Exception e) { e.printStackTrace(); } return null; }
6.在springmvc controller中加入
@RequestMapping("/socket") @Controller public class WebSocketController {
@Autowired MyMessageHandler myMessageHandler; /** * 对单个用户推送消息 * @return *
@throws ParseException */ @RequestMapping("/sendMessageByUser") @ResponseBody
public String sendMessageByUser(@RequestParam Map<String, Object> contents)
throws ParseException{ task(); return "success"; } /** * 对所有用户推送消息 * @return */
@RequestMapping("/sendMessageByAll") @ResponseBody public String
sendMessageByAll(@RequestParam Map<String, Object> contents){
myMessageHandler.sendMessageToAllUsers(contents.get("msg").toString()); return
"success"; } }
7.前端js
$(document).ready(function () { window.websocket={}; var userId='webPower';
var api='你的IP'; var app={ /** *初始化socket,判断是否支持webSocket */ initSocket:function
() { if('WebSocket' in window) { websocket = new
WebSocket("ws://"+api+"/socketServer?userId="+userId); } else if('MozWebSocket'
in window) { websocket = new
MozWebSocket("ws://"+api+"/socketServer?userId="+userId); } else { websocket =
new SockJS("http://"+api+"/sockjs/socketServer?userId="+userId); } app.state();
}, /** * 状态 */ state:function () { // 打开连接时 websocket.onopen = function(evnt) {
console.log("websocket已启用"); }; // 收到消息时 websocket.onmessage = { }; //出错时
websocket.onerror = function(evnt) { console.log("与后台握手出现问题!"); }; //关闭时
websocket.onclose = function(evnt) { console.log("正在关闭 webSocket "); }; //发送消息
// websocket.send(msg); } }; app.initSocket(); });
8.效果
热门工具 换一换