springboot + websocket + spring-messaging实现服务器向浏览器广播式
前端:
var ws;
var tt;
if(typeof(WebSocket) == "undefined") {
console.log("您的浏览器不支持WebSocket");
}else{
var wsUrl =location.protocol+location.host+"/jnetcms/myHandler";
if (wsUrl.indexOf("https") >= 0 ) {
wsUrl = wsUrl.replace("https","wss");
}else{
wsUrl = wsUrl.replace("http","ws");
}
createWebSocket();
function createWebSocket() {
try {
ws = new WebSocket(wsUrl);
init();
} catch(e) {
console.log('catch'+e);
reconnect(wsUrl);
}
}
function init() {
ws.onclose = function () {
reconnect(wsUrl);
};
ws.onerror = function() {
reconnect(wsUrl);
};
ws.onopen = function () {
heartCheck.start();
};
ws.onmessage = function (evn) {
console.log(evn);
var txt=evn.data;
var data = JSON.parse(txt);
if(data.type==1){
debugger;
tips(data.msg,"success");
if(top.document.getElementById('list').contentWindow.document.getElementById("dataTable"))
top.document.getElementById('list').contentWindow.reloadTable();
}else if(data.type==2){
tips(data.msg,"error");
var noteNum=parseInt($("#note").text());
$("#note").text(noteNum+1);
}
heartCheck.start();
}
}
var lockReconnect = false;
function reconnect(wsUrl) {
if(lockReconnect) {
return;
};
lockReconnect = true;
tt && clearTimeout(tt);
tt = setTimeout(function () {
createWebSocket(wsUrl);
lockReconnect = false;
}, 180000);
}
var heartCheck = {
timeout: 210000,
timeoutObj: null,
serverTimeoutObj: null,
start: function(){
var self = this;
this.timeoutObj && clearTimeout(this.timeoutObj);
this.serverTimeoutObj && clearTimeout(this.serverTimeoutObj);
this.timeoutObj = setTimeout(function(){
self.serverTimeoutObj = setTimeout(function() {
ws.close();
}, self.timeout);
}, this.timeout)
}
}
}
后台:
Pom文件 添加:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-websocket</artifactId>
<version>4.3.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-messaging</artifactId>
<version>4.3.7.RELEASE</version>
</dependency>
新建:MyHandler.java
import org.springframework.stereotype.Service;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketMessage;
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;
import java.util.Set;
@Service
public class MyHandler extends TextWebSocketHandler {
private static final Map<String, WebSocketSession> users;
private static final String CLIENT_ID = "username";
static {
users = new HashMap<String, WebSocketSession>();
}
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
String username= getClientId(session);
if (username != null) {
users.put(username, session);
}
}
@Override
public void handleTextMessage(WebSocketSession session, TextMessage message) {
WebSocketMessage<String> message1 = new TextMessage("server:"+message);
try {
session.sendMessage(message1);
} catch (IOException e) {
e.printStackTrace();
}
}
public boolean sendMessageToUser(String clientId, TextMessage message) {
if (users.get(clientId) == null) {
return false;
}
WebSocketSession session = users.get(clientId);
if (!session.isOpen()) {
return false;
}
try {
session.sendMessage(message);
} catch (IOException e) {
return false;
}
return true;
}
public boolean sendMessageToAllUsers(TextMessage message) {
boolean allSendSuccess = true;
Set<String> clientIds = users.keySet();
WebSocketSession session = null;
for (String clientId : clientIds) {
try {
session = users.get(clientId);
if (session.isOpen()) {
session.sendMessage(message);
}
} catch (IOException e) {
e.printStackTrace();
allSendSuccess = false;
}
}
return allSendSuccess;
}
@Override
public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
if (session.isOpen()) {
session.close();
}
users.remove(getClientId(session));
}
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
users.remove(getClientId(session));
}
@Override
public boolean supportsPartialMessages() {
return false;
}
private String getClientId(WebSocketSession session) {
try {
return (String) session.getAttributes().get(CLIENT_ID);
} catch (Exception e) {
return null;
}
}
}
新建 :WebSocketConfig.java
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(myHandler(), "/myHandler").addInterceptors(new WebSocketInterceptor()).setAllowedOrigins("*");
}
@Bean
public WebSocketHandler myHandler() {
return new MyHandler();
}
}
新建 WebSocketInterceptor.java
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.server.HandshakeInterceptor;
import javax.servlet.http.HttpSession;
import java.util.Map;
@Component
public class WebSocketInterceptor implements HandshakeInterceptor {
@Override
public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler handler, Map<String, Object> map) throws Exception {
if (request instanceof ServletServerHttpRequest) {
ServletServerHttpRequest serverHttpRequest = (ServletServerHttpRequest) request;
HttpSession session = serverHttpRequest.getServletRequest().getSession();
if (session != null) {
map.put("username", session.getAttribute("username"));
}
}
return true;
}
@Override
public void afterHandshake(ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse, WebSocketHandler webSocketHandler, Exception e) {
}
}
发送消息 :SocketController.java
import com.alibaba.druid.support.json.JSONUtils;
import com.zkjw.cms.websocket.MyHandler;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.socket.TextMessage;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.ConsoleHandler;
import java.util.logging.Handler;
@Controller
@RequestMapping("/message")
public class SocketController{
MyHandler handler=new MyHandler();
@RequestMapping(value = "/toUser",method = RequestMethod.POST)
public @ResponseBody void toUser(HttpServletRequest request) {
String username= request.getParameter("username");
String msg=request.getParameter("message");
boolean flag = handler.sendMessageToUser(username,new TextMessage(msg));
if(flag){
}
}
@RequestMapping("/toAll")
public @ResponseBody void sendMessage() {
boolean flag = handler.sendMessageToAllUsers(new TextMessage("你好"));
if(flag){
System.out.println("批量发送成功");
}
}
@RequestMapping(value="/test3",method=RequestMethod.POST)
public void test3(@RequestBody Map<String, String> map) {
String username = map.get("username");
String jsonString = JSONUtils.toJSONString(map);
boolean flag =handler.sendMessageToUser(username,new TextMessage(jsonString));
}
public void test() {
Map<String, String> map = new HashMap<String, String>();
map.put("type","2");
map.put("msg","发送成功");
String jsonString = JSONUtils.toJSONString(map);
String username = "admin";
MyHandler handler = new MyHandler();
handler.sendMessageToUser(username,new TextMessage(jsonString));
}
}