SSM框架整合WebSocket实现消息推送长连接,WebSocket实现扫码登录使⽤SSM框架整合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>
Java中
复制过去稍微改⼀下⾃⼰需要的东西就好了,这⾥的‘⼤数据’推送可以不管
不⽤在xml中配置也可以直接使⽤,使⽤时记得把过滤器的拦截放⾏‘/webSocket’请求
package com.websocket;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import urrent.ConcurrentHashMap;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import net.sf.json.JSONObject;
@ServerEndpoint("/webSocket/{type}/{uuid}")
public class WebSocket {
private static int onlineCount =0;//本来⽤统计在线⼈数的
private static Map<String, WebSocket> loginMap =new ConcurrentHashMap<String, WebSocket>();// 饿汉式
private static List<Map<String, WebSocket>> clients = null;// 懒汉式
public Session session;
public String userName;
public String uuid;
public static long timeCount =0;
/**
* 打开连接
* @param type
* @param username
* @param session
* @throws IOException
*/
@OnOpen
public void onOpen(@PathParam("type") String type,@PathParam("uuid") String uuid, Session session)throws IOException {
this.userName = type;
this.uuid = uuid;
this.session = session;
if(type != null){
if(type != null){
if(type.equals("login")){// 登录
loginMap.put(uuid,this);
}else{
if(clients == null){// ⼤数据
synchronized(WebSocket.class){
if(clients == null){
clients =new ArrayList<Map<String, WebSocket>>();
}
}
}
Map<String, WebSocket> clien =new ConcurrentHashMap<String, WebSocket>(); clien.put(uuid,this);
clients.add(clien);
}
}
//addOnlineCount();//本来⽤统计在线⼈数的
}
/**
* 删除
* @throws IOException
*/
@OnClose
public void onClose()throws IOException {
if(userName != null && userName.equals("login")){// 登录
if(loginMap != null){
}
}else{
if(clients != null){
for(int i=0; i< clients.size(); i++){// ⼤数据
Map<String, WebSocket> clien = (i);
for(WebSocket item : clien.values()){
if(item.session.equals(session))
}
}
}
}
//subOnlineCount(); //本来⽤统计在线⼈数的
}
/**
* 错误信息
*/
@OnError
public void onError(Session session, Throwable error){
error.printStackTrace();
}
/
**
* 接收数据
* @param jsonTo
* @throws IOException
*/
@OnMessage
public static void onMessage(String message)throws IOException {
JSONObject jsonTo = JSONObject.fromObject(message);
String mes =(String) ("message");
String type =(String) ("type");
String to =(String) ("To");
if(type != null){
if(type.equals("login")){// 登录
sendMessageLoginTo(mes, to);
}else if(type.equals("data")){// ⼤数据
sendMessage(mes, to);
}
}
}
}
/**
* 发给指定-登录
* @param message
* @param To
* @param mark
* @throws IOException
*/
public static void sendMessageLoginTo(String message, String To)throws IOException {
//BasicRemote().sendText(message); // 同步
//AsyncRemote().sendText(message); // 异步
if(loginMap != null){
for(WebSocket item : loginMap.values()){
if(item.uuid.equals(To))
AsyncRemote().sendText(message);
}
}
}
/**
* 发给指定-⼤数据
* @param message
* @param To
* @param mark
* @throws IOException
*/
public static void sendMessage(String message, String to)throws IOException {
if(clients != null){// ⼤数据
for(int i=0; i< clients.size(); i++){// 这⾥(循环中套了个循环判断,⽤了线程加⾃带的异步推送)
new WebSocketThread(i,clients, to, message).start();// 这⾥写到另⼀个类上了参考下⾯两个(暂时不⽤)的就好}
}
// 说明:如果多个消息推送使⽤同⼀个session推送消息,socket多线程冲突
// 报错:webSocket多线程推送出错,报错信息为The remote endpoint was in state [TEXT_PARTIAL_WRITING] // 建议使⽤:Thread.sleep(100); 根据同⼀个session判断(⾃⼰写咯)
}
/**
* 发给指定-⼤数据(暂时不⽤)
* @param message
* @param To
* @param mark
* @throws IOException
*/
public static void sendMessageTo(String message, String to)throws IOException {
if(clients != null){// ⼤数据
for(int i=0; i< clients.size(); i++){
Map<String, WebSocket> clien = (i);
for(WebSocket item : clien.values()){
if(item.uuid.equals(to))
AsyncRemote().sendText(message);
}
}
}
}
/**
* 发给全部 -⼤数据(暂时不⽤)
* @param message
* @throws IOException
*/
public static void sendMessageAll(String message)throws IOException {
for(int i=0; i< clients.size(); i++){
Map<String, WebSocket> clien = (i);
for(WebSocket item : clien.values()){
AsyncRemote().sendText(message);
}
}
}
public static synchronized int getOnlineCount(){
return onlineCount;
}
}
public static synchronized void addOnlineCount(){
}
public static synchronized void subOnlineCount(){
}
public static synchronized Map<String, WebSocket>getLoginMap(){
return loginMap;
}
public static synchronized List<Map<String, WebSocket>>getClients(){
return clients;
}
}
JS中
websocket是html5⾃带的协议
这⾥的⼆维码⽣成⽅式和路径参数我就不写了
我是使⽤了UUID传到⼿机确认的,UUID是我存放到后台Java中的键值对标识
var websocket =null;websocket和socket
var host = document.location.host;
var judgeTemp =0;
var temp_uuid;
// 其他地⽅调⽤初始化websocket连接
function openWebSorket(uuid){// uuid 是⽣成的⼆维码参数传到⼿机,然后确认登录后传回来后台对应推送的 temp_uuid = uuid;
createWebSorket(uuid);
}
function createWebSorket(uuid){
try{
//判断当前浏览器是否⽀持WebSocket
if('WebSocket'in window){
websocket =new WebSocket('ws://'+ host +'/securityIntelligence/webSocket/login/'+uuid); initEventHandle();
}else{
alert('当前浏览器⽆法使⽤扫码登录');
}
}catch(err){
loadTemp++;
if(loadTemp ==5){// 重连5 次不⾏就重新刷新浏览器
load();
}
console.log(err)
console.ssage);
setTimeout(function(){
createWebSorket(uuid);// 由于⽹络问题可能⽆法连接(两秒后重新连接)
},2000)
}
}
function initEventHandle(){
//连接发⽣错误的回调⽅法
judgeTemp =1;
console.log('扫码登录连接失败');
};
//连接成功建⽴的回调⽅法
console.log('扫码登录连接成功');
console.log('扫码登录连接成功');
}
//接收到消息的回调⽅法
console.log('扫码回馈消息');
setMessageInnerHTML(event.data);
}
//连接关闭的回调⽅法
console.log('扫码登录连接关闭');
if(judgeTemp !=1){
createWebSorket(temp_uuid);
}
}
//监听窗⼝关闭事件,当窗⼝关闭时,主动去关闭websocket连接,防⽌连接还没断开就关闭窗⼝,server端会抛异常。 beforeunload=function(){
judgeTemp =1;
closeWebSocket();
}
}
//关闭WebSocket连接
function closeWebSocket(){
websocket.close();
}
/**
* ⼿机端确定登录后页⾯登录跳转主页
* @returns
*/
function setMessageInnerHTML(data){
judgeTemp =1;
if(tempNum ==0){// tempNum 全局的防⽌重复点击登录⽤的,这⾥直接拿过来的不改了
tempNum =1;
$('#submit').addClass('layui-btn-disabled');
$('#submit').html("正在登录中...");
$.post(systemPath+"login/login",{},function(data){// 这⾥参数和推送的⾃⼰定义
layer.msg(data.msg,{"zIndex":9999999999,"offset":"15%"})
if(data.success){// 登录成功了
closeWebSocket();
window.location.href = systemPath+"page/main";
}
tempNum =0;
$('#submit').removeClass('layui-btn-disabled');
$('#submit').html("登 ;录");
})
}
}
以上就是我写的websocket扫码登录了,长连接也实现了
我没有把所有的页⾯代码放上来,但是⽂字已经说明了使⽤,看不懂我就没有办法咯
本⼈使⽤的框架是:
Spring + Spring MVC + Mybatis + Sql server + Layui
发布后Nginx代理报错问题解决:
websocket连接错误Error during WebSocket handshake Unexpected response code 404
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论