springboot集成websocket
导入maven依赖
<!--websocket-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
编写WebSocketConfig,启动时加载
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
@Configuration
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}
websocket实现
接口
import javax.websocket.Session;
public interface WebsocketService {
/**
* 连接建立成功调用的方法
* @param session
*/
void onOpen(Session session);
/**
* 连接关闭调用的方法
*/
void onClose();
/**
* 收到客户端消息后调用的方法
* @param message
* @param session
*/
void onMessage(String message, Session session);
/**
* 发生错误
* @param session
* @param error
*/
void onError(Session session, Throwable error);
}
实现类
只有一个聊天室 不分参数
import com.alibaba.druid.support.json.JSONUtils;
import com.alibaba.fastjson.JSON;
import com.tel.common.cache.CacheByRedis;
import com.tel.common.contant.TelConstants;
import com.tel.dao.model.TelGift;
import com.tel.dao.model.TelGiftExample;
import com.tel.dao.model.TelLoginUser;
import com.tel.dao.model.TelLoginUserExample;
import com.tel.dao.vo.OnLinePeopleVO;
import com.tel.service.TelGiftService;
import com.tel.service.TelLoginUserService;
import com.tel.service.WebsocketService;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@ServerEndpoint("/im")
@Component
public class WebsocketServiceImpl implements WebsocketService {
private static Logger log = LoggerFactory.getLogger(WebsocketServiceImpl.class);
//静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
private static int onlineCount = 0;
//旧:concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。
//private static CopyOnWriteArraySet<ImController> webSocketSet = new CopyOnWriteArraySet<ImController>();
//与某个客户端的连接会话,需要通过它来给客户端发送数据
private Session session;
//新:使用map对象,便于根据userId来获取对应的WebSocket
private static ConcurrentHashMap<String,WebsocketServiceImpl> websocketList = new ConcurrentHashMap<>();
// private static ConcurrentHashMap<String,WebsocketServiceImpl> websocketList = new ConcurrentHashMap<>();
//接收sid
private String userId="";
@Override
@OnOpen
public void onOpen(Session session) {
this.session = session;
websocketList.put(userId,this);
// log.info("websocketList->"+ JSON.toJSONString(websocketList));
addOnlineCount(); //在线数加1
log.info("有新窗口开始监听:"+",当前在线人数为" + getOnlineCount());
this.userId=userId;
try {
sendMessage("连接成功");
} catch (IOException e) {
log.error("websocket IO异常");
}
}
@Override
@OnClose
public void onClose() {
if(websocketList.get(this.userId)!=null){
websocketList.remove(this.userId);
//webSocketSet.remove(this); //从set中删除
subOnlineCount(); //在线数减1
log.info("有一连接关闭!当前在线人数为" + getOnlineCount());
}
}
@Override
@OnMessage
public void onMessage(String message, Session session) {
log.info("收到来自窗口"+userId+"的信息:"+message);
//处理业务
}
@Override
@OnError
public void onError(Session session, Throwable error) {
log.error("发生错误");
error.printStackTrace();
}
/**
* 实现服务器主动推送
*/
public void sendMessage(String message) throws IOException {
this.session.getBasicRemote().sendText(message);
}
public static synchronized int getOnlineCount() {
return onlineCount;
}
public static synchronized void addOnlineCount() {
WebsocketServiceImpl.onlineCount++;
}
public static synchronized void subOnlineCount() {
WebsocketServiceImpl.onlineCount--;
}
}
带参数,区分聊天室
import com.alibaba.druid.support.json.JSONUtils;
import com.alibaba.fastjson.JSON;
import com.tel.common.cache.CacheByRedis;
import com.tel.common.contant.TelConstants;
import com.tel.dao.model.TelGift;
import com.tel.dao.model.TelGiftExample;
import com.tel.dao.model.TelLoginUser;
import com.tel.dao.model.TelLoginUserExample;
import com.tel.dao.vo.OnLinePeopleVO;
import com.tel.service.TelGiftService;
import com.tel.service.TelLoginUserService;
import com.tel.service.WebsocketService;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@ServerEndpoint("/im/{userId}")
@Component
public class WebsocketServiceImpl implements WebsocketService {
private static Logger log = LoggerFactory.getLogger(WebsocketServiceImpl.class);
//静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
private static int onlineCount = 0;
//旧:concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。
//private static CopyOnWriteArraySet<ImController> webSocketSet = new CopyOnWriteArraySet<ImController>();
//与某个客户端的连接会话,需要通过它来给客户端发送数据
private Session session;
//新:使用map对象,便于根据userId来获取对应的WebSocket
private static ConcurrentHashMap<String,WebsocketServiceImpl> websocketList = new ConcurrentHashMap<>();
// private static ConcurrentHashMap<String,WebsocketServiceImpl> websocketList = new ConcurrentHashMap<>();
//接收sid
private String userId="";
@Override
@OnOpen
public void onOpen(Session session,@PathParam("userId") String userId) {
this.session = session;
websocketList.put(userId,this);
log.info("websocketList->"+ JSON.toJSONString(websocketList));
addOnlineCount(); //在线数加1
log.info("有新窗口开始监听:"+",当前在线人数为" + getOnlineCount());
this.userId=userId;
try {
sendMessage("连接成功");
} catch (IOException e) {
log.error("websocket IO异常");
}
}
@Override
@OnClose
public void onClose() {
if(websocketList.get(this.userId)!=null){
websocketList.remove(this.userId);
//webSocketSet.remove(this); //从set中删除
subOnlineCount(); //在线数减1
log.info("有一连接关闭!当前在线人数为" + getOnlineCount());
}
}
@Override
@OnMessage
public void onMessage(String message, Session session) {
log.info("收到来自窗口"+userId+"的信息:"+message);
//处理业务
}
@Override
@OnError
public void onError(Session session, Throwable error) {
log.error("发生错误");
error.printStackTrace();
}
/**
* 实现服务器主动推送
*/
public void sendMessage(String message) throws IOException {
this.session.getBasicRemote().sendText(message);
}
public static synchronized int getOnlineCount() {
return onlineCount;
}
public static synchronized void addOnlineCount() {
WebsocketServiceImpl.onlineCount++;
}
public static synchronized void subOnlineCount() {
WebsocketServiceImpl.onlineCount--;
}
}
测试 新建jsp页面测试
修改socketUrl为你自己的路径
<%--
Created by IntelliJ IDEA.
User: as
Date: 2020/4/25
Time: 13:48
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<meta charset="utf-8">
<title>websocket通讯</title>
</head>
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.js"></script>
<script>
var socket;
function openSocket() {
if(typeof(WebSocket) == "undefined") {
console.log("您的浏览器不支持WebSocket");
}else{
console.log("您的浏览器支持WebSocket");
//实现化WebSocket对象,指定要连接的服务器地址与端口 建立连接
//等同于socket = new WebSocket("ws://localhost:8888/xxxx/im/25");
<%--//var socketUrl="${request.contextPath}/im/"+$("#userId").val();--%>
// var socketUrl="ws://192.168.31.5:17654/im/"+$("#userId").val();
// var socketUrl="ws://192.168.31.5:8080/tel/im";
var socketUrl="http://192.168.31.5:8080/im";
// var socketUrl="http://localhost:17654/im";
// var socketUrl="http://localhost:17654/im/"+$("#userId").val();
socketUrl=socketUrl.replace("https","ws").replace("http","ws");
console.log(socketUrl)
socket = new WebSocket(socketUrl);
//打开事件
socket.onopen = function() {
console.log("websocket已打开");
//socket.send("这是来自客户端的消息" + location.href + new Date());
};
//获得消息事件
socket.onmessage = function(msg) {
console.log(msg.data);
//发现消息进入 开始处理前端触发逻辑
$("#response").html(msg);
};
//关闭事件
socket.onclose = function() {
console.log("websocket已关闭");
};
//发生了错误事件
socket.onerror = function() {
console.log("websocket发生了错误");
}
}
}
function sendMessage() {
if(typeof(WebSocket) == "undefined") {
console.log("您的浏览器不支持WebSocket");
}else {
console.log("您的浏览器支持WebSocket");
console.log('[{"toUserId":"'+$("#toUserId").val()+'","contentText":"'+$("#contentText").val()+'"}]');
socket.send('[{"toUserId":"'+$("#toUserId").val()+'","contentText":"'+$("#contentText").val()+'"}]');
}
}
function showResponse(message){
$("#response").html(message);
}
</script>
<body>
<p>【userId】:<div><input id="userId" name="userId" type="text" value="25"></div>
<p>【toUserId】:<div><input id="toUserId" name="toUserId" type="text" value="26"></div>
<p>【toUserId】:<div><input id="contentText" name="contentText" type="text" value="嗷嗷嗷"></div>
<p>【操作】:<div><a onclick="openSocket()">开启socket</a></div>
<p>【操作】:<div><a onclick="sendMessage()">发送消息</a></div>
<p><div id = "response" name ="response"></div>
</body>
</html>>
springboot集成jsp
请参考下面的文章自行集成jsp,这里不做过多演示
springboot集成jsp