Websocket创建步骤

总共是三个步骤

一、创建webSocketHandler处理器继承TextWebSocketHandler 

@component

public class MyWebSocketHandler extends TextWebSocketHandler 

 

1.定义一个成员变量,保存用户与对应的WebSocketSession对应关系

public static final Map<String, WebSocketSession> userSocketSessionMap;

初始化

static {

  userSocketSessionMap = new HashMap<StringWebSocketSession>();

}

2.建立连接之后就保存每个用户和webSocketSession

/**
* 建立连接后
*/
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
  Long uid = (Long) session.getAttributes().get("uid");
  if (userSocketSessionMap.get(uid) == null) {
    userSocketSessionMap.put(uid, session);
  }
}

3.

/**
* 消息处理,在客户端通过Websocket API发送的消息会经过这里,然后进行相应的处理,在这里可以进行消息的推送

不在这里面推送就直接就调用父类方法

/**
* js调用websocket.send时候,会调用该方法
*/
@Override
protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
super.handleTextMessage(session, message);
}


*/
public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception {
if(message.getPayloadLength()==0)return;
Message msg=new Gson().fromJson(message.getPayload().toString(),Message.class);
msg.setDate(new Date());
sendMessageToUser(msg.getTo(), new TextMessage(new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create().toJson(msg)));
}

4.消息传输错误处理

/**
* 消息传输错误处理
*/
public void handleTransportError(WebSocketSession session,
Throwable exception) throws Exception {
if (session.isOpen()) {
session.close();
}
Iterator<Entry<Long, WebSocketSession>> it = userSocketSessionMap
.entrySet().iterator();
// 移除Socket会话
while (it.hasNext()) {
Entry<Long, WebSocketSession> entry = it.next();
if (entry.getValue().getId().equals(session.getId())) {
userSocketSessionMap.remove(entry.getKey());
System.out.println("Socket会话已经移除:用户ID" + entry.getKey());
break;
}
}
}

5.关闭连接

/**
* 关闭连接后
*/
public void afterConnectionClosed(WebSocketSession session,
CloseStatus closeStatus) throws Exception {
System.out.println("Websocket:" + session.getId() + "已经关闭");
Iterator<Entry<Long, WebSocketSession>> it = userSocketSessionMap
.entrySet().iterator();
// 移除Socket会话
while (it.hasNext()) {
Entry<Long, WebSocketSession> entry = it.next();
if (entry.getValue().getId().equals(session.getId())) {
userSocketSessionMap.remove(entry.getKey());
System.out.println("Socket会话已经移除:用户ID" + entry.getKey());
break;
}
}
}

6.给指定的用户推送信息

/**
* 给某个用户发送消息
*
* @param userName
* @param message
* @throws IOException
*/
public void sendMessageToUser(Long uid, TextMessage message)
throws IOException {
WebSocketSession session = userSocketSessionMap.get(uid);
if (session != null && session.isOpen()) {
session.sendMessage(message);
}
}

二、websocket拦截器HandShakeInterceptor,建立连接握手和断开

01在握手之前执行该方法,继续握手返回true中断返回false

public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception {
System.out.println("Websocket:用户[ID:" + ((ServletServerHttpRequest) request).getServletRequest().getSession(false).getAttribute("uid") + "]已经建立连接");
if (request instanceof ServletServerHttpRequest) {
ServletServerHttpRequest servletRequest = (ServletServerHttpRequest) request;
HttpSession session = servletRequest.getServletRequest().getSession(false);
// 标记用户
Long uid = (Long) session.getAttribute("uid");
if(uid!=null){
attributes.put("uid", uid);
}else{
return false;
}
}
return true;
}

02握手之后执行的方法,无论握手成功都会指明了响应状态码和响应头,这个方法一般都是空实现

public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception exception) {
}

三、WebSocket配置处理器,在这里面把处理器和拦截器都注册进来

/**
* WebScoket配置处理器
* @author Goofy
* @Date 2015年6月11日 下午1:15:09
*/
@Component
@EnableWebSocket
public class WebSocketConfig extends WebMvcConfigurerAdapter implements WebSocketConfigurer

01定义一个handler成员变量用@Autowired注入进来

@Autowired
private SpringWebSocketHandler springWebSocketHandler;

02添加handler和拦截器

public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(springWebSocketHandler, "/websocket/socketServer").addInterceptors(new SpringWebSocketHandlerInterceptor());
registry.addHandler(springWebSocketHandler, "/sockjs/socketServer").addInterceptors(new SpringWebSocketHandlerInterceptor()).withSockJS();
}

四、创建一个Controller进行测试

@Controller
public class WebsocketController {
@Bean//这个注解会从Spring容器拿出Bean
public SpringWebSocketHandler infoHandler() {
return new SpringWebSocketHandler();
}

登录,保存用户到session

@RequestMapping("/websocket/login")
@ResponseBody
public String login(HttpServletRequest request, ModelMap model) throws Exception {
String username = request.getParameter("username");
System.out.println(username+"登录");
request.getSession().setAttribute("WEBSOCKET_USERNAME", username);
return "websocket";
}

消息推送,也可以在消息处理handleTextMessage中去做

@RequestMapping("/websocket/send")
@ResponseBody
public String send(HttpServletRequest request, ModelMap model) {
//String username = model.get
try {
System.out.println("session===" + request.getSession().getAttribute("WEBSOCKET_USERNAME"));
infoHandler().sendMessageToUser("zhangsan", new TextMessage("你好,测试!!!!"));
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}

原文地址:https://www.cnblogs.com/handsome1013/p/9390609.html