SSM+JSP项目中加入了websocket的消息推送
app端与网页端通信
以下代码只是讲解答大体思路
<%@ page language="java" pageEncoding="UTF-8"%>
<%@ include file="/WEB-INF/views/include/taglib.jsp"%>
<html>
<head>
//外链各种样式
<!-- <link rel="stylesheet"
href="//cdn.bootcss.com/bootstrap/3.3.5/css/bootstrap.min.css">
<link rel="stylesheet"
href="//cdn.bootcss.com/bootstrap/3.3.5/css/bootstrap-theme.min.css">
<script src="//cdn.bootcss.com/jquery/1.11.3/jquery.min.js"></script>
<script src="//cdn.bootcss.com/bootstrap/3.3.5/js/bootstrap.min.js"></script> -->
<meta name="decorator" content="v5" />
<link href="${ctxStatic}/v5/css/content.css" type="text/css"
rel="stylesheet" />
<title></title>
<script type="text/javascript">
//分页
function page(n, s) {
$("#pageNo").val(n);
$("#pageSize").val(s);
$("#searchForm").submit();
return false;
}
var websocket;
if ('WebSocket' in window) {
console.log("此浏览器支持websocket");
websocket = new WebSocket("ws://192.168.1.172:8080/项目名/webSocketServer?username=${userId}&ie=1");//传参数的方式
} else if ('MozWebSocket' in window) {
alert("此浏览器只支持MozWebSocket");
} else {
alert("此浏览器只支持SockJS");
}
websocket.onopen = function(evnt) {
$("#tou").html("链接服务器成功!")
};
//实时显示推送的消息
websocket.onmessage = function(evnt) {
if(evnt.data.indexOf("|") >= 0 ){
var msg=evnt.data.split("|");
if(msg[1]==1){
$("#"+msg[0]).html("开");
$("#"+msg[0]+"2").html("关闭");
}else{
$("#"+msg[0]).html("关");
$("#"+msg[0]+"2").html("开启");
}
}else{
alert(evnt.data);
}
};
websocket.onerror = function(evnt) {
$("#tou").html("遇到了错误")
};
websocket.onclose = function(evnt) {
$("#tou").html("与服务器断开了链接!")
}
$('#send').bind('click', function() {
senda(111);
});
function senda(deviceId,deviceS100Id) {
var open;
if($("#"+deviceId).html()=="开"){
open=0;
}else{
open=1;
}
var message = deviceId+"|"+open+"|"+deviceS100Id+"|1";
if (websocket != null) {
//var message = $("#message").val();
websocket.send(message);
} else {
alert('未与服务器链接.');
}
}
</script>
</head>
<body>
<div class="page-header" id="tou"></div>
<div class="table_wrapper animated fadeInRight">
<sys:message content="${message}" />
<table id="contentTable"
class="table table-striped table-condensed table-ys "
style='table-layout: fixed' width="100%">
<thead>
<tr>
<th>门禁编号</th>
<th>状态</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<c:forEach items="${page.list}" var="appDevice">
<tr>
<td>${appDevice.deviceId}</td>
<td id="${appDevice.deviceId}"></td>
<td><a href="#" onclick="senda('${XXX}','${XXX}')" id="${XXX}2">开启</a>
//id为动态生成,方便jq查找
</td>
</tr>
</c:forEach>
</tbody>
</table>
<div class="pagination">${page}</div>
</div>
</body>
</html>
展示
**
## WebSocketConfig.java
**
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
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 extends WebMvcConfigurerAdapter implements
WebSocketConfigurer {
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(WebSocketPushHandler(), "/webSocketServer")
.addInterceptors(new MyWebSocketInterceptor());
registry.addHandler(WebSocketPushHandler(), "/sockjs/webSocketServer")
.addInterceptors(new MyWebSocketInterceptor()).withSockJS();
}
@Bean
public WebSocketHandler WebSocketPushHandler() {
return new WebSocketPushHandler();
}
}
**
## MyWebSocketInterceptor.java
**
import org.springframework.core.Constants;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.server.HandshakeInterceptor;
import org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.Map;
/**
* 此类用来获取登录用户信息并交由websocket管理
* @author ts
*
*/
public class MyWebSocketInterceptor extends HttpSessionHandshakeInterceptor {
@Override
public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,
Map<String, Object> attributes) throws Exception {
// TODO Auto-generated method stub
System.out.println("Before Handshake");
//接受jsp传来的参数
String userName = ((ServletServerHttpRequest) request).getServletRequest().getParameter("username");
String ie = ((ServletServerHttpRequest) request).getServletRequest().getParameter("ie");
//将参数放到attributes
if(userName!=null){
attributes.put("WEBSOCKET_DEVICEID",userName);
}
attributes.put("ie",ie);
return super.beforeHandshake(request, response, wsHandler, attributes);
}
@Override
public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,
Exception ex) {
// TODO Auto-generated method stub
super.afterHandshake(request, response, wsHandler, ex);
}
}
**
## WebSocketPushHandler
**
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.socket.*;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 消息处理类
*
* @author ts
*
*/
public class WebSocketPushHandler implements WebSocketHandler {
@Autowired
private DoorStatusService doorStatusService;
@Autowired
private AppDeviceService appDeviceService;
@Autowired
private SystemService systemService;
// 保存ie链接
private static Map<String, WebSocketSession> map = new HashMap<String, WebSocketSession>();
// 保存app的连接
private static Map<String, WebSocketSession> mapApp = new HashMap<String, WebSocketSession>();
// 静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
private static int onlineCount = 0;
// 用户进入系统监听
@Override
public void afterConnectionEstablished(WebSocketSession session)
throws Exception {
//得到参数
String id = (String) session.getAttributes().get("WEBSOCKET_DEVICEID");
String ie = (String) session.getAttributes().get("ie");
//1为网页端的连接。0为app端的连接
if ("1".equals(ie)) {
map.put(id, session);
System.out.println("ie成功进入了系统。标识id:" + id);
} else {
mapApp.put(id, session);
System.out.println("app成功进入了系统。标识id:" + id);
}
onlineCount++;
System.out.println("当前在线数:" + onlineCount);
}
//发来的消息
@Override
public void handleMessage(WebSocketSession session,
WebSocketMessage<?> message) throws Exception {
System.out.println("客户端发来的消息:"+message.getPayload());
}
// 后台错误信息处理方法
@Override
public void handleTransportError(WebSocketSession session,
Throwable exception) throws Exception {
}
// 用户退出后的处理,不如退出之后,要将用户信息从websocket的session中remove掉,这样用户就处于离线状态了,也不会占用系统资源
@Override
public void afterConnectionClosed(WebSocketSession session,
CloseStatus closeStatus) throws Exception {
if (session.isOpen()) {
session.close();
}
onlineCount--;
System.out.println("当前在线数:" + onlineCount);
Collection<WebSocketSession> col = map.values();
while (true == col.contains(session)) {
System.out.println("安全退出了系统。。标识id" + map.keySet());
col.remove(session);
}
}
@Override
public boolean supportsPartialMessages() {
return false;
}
/**
* 给所有的用户发送消息
*/
public void sendMessagesToUsers(TextMessage message) {
}
/**
* 发送消息给ie
* */
public void sendMessageToUser(String deviceId, TextMessage message,
User user) {
//编辑消息后sendMessage()方法进行消息推送
TextMessage message1 = new TextMessage(msg);
(message1);
map.get(XXX).sendMessage(message1);
}
//推送到app
public void sendMessageToapp(String deviceId, TextMessage message,User user,String deviceS100Id){
// 遍历map。找到对应的app
for (String key : mapApp.keySet()) {
if (key.equals(deviceId)) {
try {
if (mapApp.get(key).isOpen()) {
mapApp.get(key).sendMessage(message);
System.out.println("发送成功,设备码:" + key);
// 保存数据库
XXXX
return;
} else {
System.out.println("设备不在线,未发送,设备号:" + deviceId);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
System.out.println("提示:设备未上线!" + deviceId);
TextMessage message1 = new TextMessage("提示:设备未上线!");
try {
map.get(user.getId()).sendMessage(message1);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}