RT:
最近项目里面需要这么一个功能,每天定时的从消息队列里面读取数据,正常的进行存储,异常的在前端页面进行报警提醒;
然后就用到了websocket。
步骤如下:
1、首先pom文件添加依赖包
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
2、接着添加配置(采用注解的方式)
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
@Autowired
@Qualifier(value = "myWebSocketHandler")
private MyWebSocketHandler webSocketHandler;
@Autowired
@Qualifier(value = "wsInterceptor")
private WSInterceptor wsInterceptor;
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry webSocketHandlerRegistry) {
webSocketHandlerRegistry
.addHandler(webSocketHandler, "/websocket")
.addInterceptors(wsInterceptor)
.setAllowedOrigins("*");;
}
}
这里说明一下:
@Configuration 说明此类作为spring的配置
@EnableWebSocket 开启websocket的支持
webSocketHandlerRegistry.addHandler(webSocketHandler, "/websocket")是注册websocket的实现类(WebSocketHandler),"/websocket"是访问websocket的地址;
addInterceptors的作用是添加websocke拦截器,可以在握手之前,握手之后进行某些自定义操作;
setAllowedOrigins的作用用来设置来自那些域名的请求可访问,默认为localhost
3、接着是握手拦截器
@Component
@Qualifier("wsInterceptor")
public class WSInterceptor extends HttpSessionHandshakeInterceptor {
@Override
public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,
Map<String, Object> attributes) throws Exception {
//握手之前执行
// 这里将登陆的信息保存到attributes里,在接下来的实现里面可以通过session.getAttributes()
// 拿到attributes里面的参数
return super.beforeHandshake(request,response,wsHandler,attributes);
}
@Override
public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception arg3) {
// TODO Auto-generated method stub
}
}
4、下面是实现类
@Component
@Qualifier("myWebSocketHandler")
public class MyWebSocketHandler implements WebSocketHandler {
public static final Map<String, WebSocketSession> userSocketSessionMap;
static {
userSocketSessionMap = new HashMap<String, WebSocketSession>();
}
@Override
public void afterConnectionEstablished(WebSocketSession webSocketSession) throws Exception {
//建立连接之后执行
Map<String, Object> attributes = webSocketSession.getAttributes();
Object userId = attributes.get("userId");
if (userId != null) {
System.out.println("WebSocket连接成功:" + userId);
userSocketSessionMap.put(userId.toString(), webSocketSession);
} else {
System.out.println("WebSocket找不到userId");
}
}
//这里是我自定义的发送消息的方法
public void sendMessageToUser(String userName, Integer category, String msg) throws
IOException {
Iterator<Map.Entry<String, WebSocketSession>> it = userSocketSessionMap
.entrySet().iterator();
Map<String, Object> map = new HashMap<String, Object>();
map.put("type", category);
map.put("msg", msg);
final TextMessage message = new TextMessage(JsonHelper.beanToJson(map));
while (it.hasNext()) {
final Map.Entry<String, WebSocketSession> user = it.next();
if (user.getKey().equals(userName) && user.getValue().isOpen()) {
new Thread(new Runnable() {
@Override
public void run() {
try {
if (user.getValue().isOpen()) {
user.getValue().sendMessage(message);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
}
}
@Override
public void handleMessage(WebSocketSession webSocketSession, WebSocketMessage<?> webSocketMessage) throws Exception {
//接收到消息执行
}
@Override
public void handleTransportError(WebSocketSession webSocketSession, Throwable throwable) throws Exception {
}
@Override
public void afterConnectionClosed(WebSocketSession webSocketSession, CloseStatus closeStatus) throws Exception {
//连接关闭之后执行
}
@Override
public boolean supportsPartialMessages() {
return false;
}
}
这里说明一下,WebSocketHandler实现类除了自带的方法,由于业务需要我自定义了一个方法用来给用户推送消息,在每次建立连接之后将用户的信息保存到userSocketSessionMap里面。在后面自定义sendMessageToUser方法里面,通过遍历每一组map进行消息推送。
5、最后是客户端
客户端就不全部贴出来了,只放一些js吧;
//加入连接websocket代码 begin
var websocket = null;
var host = cfg.path.substr(cfg.path.indexOf('//'));
if ('WebSocket' in window) {
//建立连接websocket客户端
websocket = new WebSocket("ws:" + host + "/websocket");
websocket.onopen = function onOpen(openEvt) {
//websocket建立连接时触发
};
websocket.onmessage = function onMessage(evt) {
//当接收到来自服务器的消息时触发
};
websocket.onerror = function onError() {
//websocket发生错误时触发
};
websocket.onclose = function onClose() {
//websocket关闭连接时触发
};
} else
alert("浏览器不支持消息推送");
//加入连接websocket代码 end
这些是在实际项目里面用到的,为了加深印象在这里记录一下,当然websocke实现的方式有很多;能实现业务需求的就是合适的。