Spring Boot中使用Websocket搭建即时聊天系统
1、首先在pom文件中引入Webscoekt的依赖
<!-- websocket依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
2、通过注解方式构建Websocket服务
package com.kk.server.chat.websocket; import com.kk.server.chat.service.CheckTokenService;
import com.kk.server.chat.service.QueryService;
import com.kk.server.chat.service.SaveMongodbService;
import org.apache.log4j.Logger;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component; import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; /**
* Created by yxl on 2018-03-19.
*/
@ServerEndpoint("/chat/{userId}") //关键注解,将WebSocket服务端运行在 ws://[Server端IP或域名]:[Server端口]/websockets/chat/{userId} 的访问端点,客户端浏览器已经可以对 WebSocket客户端API发起HTTP长连接了。
@Component
public class ChatWebsocket { private Logger logger = Logger.getLogger(ChatWebsocket.class); private static ApplicationContext applicationContext; private SaveMongodbService saveMongodbService; private CheckTokenService checkTokenService; private QueryService queryService; //静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
private static int onlineCount = 0;
//concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。若要实现服务端与单一客户端通信的话,可以使用Map来存放,其中Key可以为用户标识
private static Map<String, Session> webSocketSet = new ConcurrentHashMap<>(); //医生web //解决Websocket不能注入bean的问题
public static void setApplicationContext(ApplicationContext applicationContext) {
ChatWebsocket.applicationContext = applicationContext;
} /**
* 连接建立成功调用的方法
*
* @param userId 用户链接ID
*/
@OnOpen //建立连接的注解,当用户建立连接时SpringBoot会监听到,然后会调用该注解下的方法
public void onOpen(@PathParam("userId") String userId, Session session) {
webSocketSet.put(userId, session);
} /**
* 连接关闭调用的方法
*/
@OnClose
public void onClose(Session session) {
logger.info("进入关闭方法!");
if (session != null) {
Map<String, String> pathParameters = session.getPathParameters();
String userId = pathParameters.get("userId"); //从当前关闭session中获取用户ID,前提是建立websocket连接时带有userId,即 @ServerEndpoint("/chat/{userId}")
webSocketSet.remove(userId); //从map中移除用户
}
} /**
* 收到客户端消息后调用的方法
*
* @param message 客户端发送过来的消息
* @param session 可选的参数
*/
@OnMessage
public void onMessage(String message, Session session) throws IOException { try {
JSONObject jsonObject = JSONObject.parseObject(message);
String receiver_id = jsonObject.getString("receiver_id") //接受者ID,通过该Id来获取接受者的session
Session session = webSocketSet.get("receiver_id")
if (session != null) {
session.getBasicRemote.sendText(message); //通过session发送消息
}else {
//TODO 接收方不在线,处理离线消息 }
}catch(IOException e) {
e.printStackTrace;
} } /**
* 发生错误时调用
*
* @param session
* @param error
*/
@OnError
public void onError(Session session, Throwable error) {
//onClose();
if (session != null) {
Map<String, String> pathParameters = session.getPathParameters();
String userId = pathParameters.get("userId"); //从当前关闭session中获取用户ID,前提是建立websocket连接时带有userId,即 @ServerEndpoint("/chat/{userId}")
webSocketSet.remove(userId); //从map中移除用户
}
logger.info("webscoket发生错误!"+error.getMessage());
error.printStackTrace();
}
}
3、前台调用方法(js)
function WebSocketTest()
{
if ("WebSocket" in window)
{
alert("您的浏览器支持 WebSocket!"); // 打开一个 web socket
var ws = new WebSocket("ws://服务器IP:端口/chat/123");
ws.onopen = function() {
// Web Socket 已连接上,使用 send() 方法发送数据
ws.send('{"userId":"1555855","message" : "test"}');
ws.close("666666");
alert("数据发送中...");
};
ws.onmessage = function (evt) {
console.log(evt)
alert(evt.data);
alert("数据已接收...");
}; ws.onclose = function(){
// 关闭 websocket
alert("连接已关闭...");
};
}else {
// 浏览器不支持 WebSocket
alert("您的浏览器不支持 WebSocket!");
}
}
4、当然,在使用websocket聊天时,可能会遇到一些数据需要查询数据库或者Redis,但是在websocket中又不能直接注入相应的Bean实例,这个时候可以看我的另一篇博客https://www.cnblogs.com/Amaris-Lin/p/9038813.html
Spring Boot中使用Websocket搭建即时聊天系统的更多相关文章
- 在spring boot中使用webSocket组件(二)
该篇演示如何使用websocket创建一对一的聊天室,废话不多说,我们马上开始! 一.首先先创建前端页面,代码如下图所示: 1.login.html <!DOCTYPE html> < ...
- 在spring boot中使用webSocket组件(一)
最近在项目中使用到了spring的webSocket组件,在这里和大家分享下,如有错误,欢迎大家指正. 在这里我使用的IDE工具是Intellij idea,框架是spring boot.spring ...
- Spring Boot 中使用 WebSocket 实现一对多聊天及一对一聊天
为什么需要WebSocket? 我们已经有了http协议,为什么还需要另外一个协议?有什么好处? 比如我想得到价格变化,只能是客户端想服务端发起请求,服务器返回结果,HTTP协议做不到服务器主动向客户 ...
- spring boot / cloud (十七) 快速搭建注册中心和配置中心
spring boot / cloud (十七) 快速搭建注册中心和配置中心 本文将使用spring cloud的eureka和config server来搭建. 然后搭建的模式,有很多种,本文主要聊 ...
- Spring Boot 中的静态资源到底要放在哪里?
当我们使用 SpringMVC 框架时,静态资源会被拦截,需要添加额外配置,之前老有小伙伴在微信上问松哥Spring Boot 中的静态资源加载问题:"松哥,我的HTML页面好像没有样式?& ...
- (转)Spring Boot 2 (十):Spring Boot 中的响应式编程和 WebFlux 入门
http://www.ityouknow.com/springboot/2019/02/12/spring-boot-webflux.html Spring 5.0 中发布了重量级组件 Webflux ...
- Spring Boot 2 (十):Spring Boot 中的响应式编程和 WebFlux 入门
Spring 5.0 中发布了重量级组件 Webflux,拉起了响应式编程的规模使用序幕. WebFlux 使用的场景是异步非阻塞的,使用 Webflux 作为系统解决方案,在大多数场景下可以提高系统 ...
- 学习Spring Boot:(二十三)Spring Boot 中使用 Docker
前言 简单的学习下怎么在 Spring Boot 中使用 Docker 进行构建,发布一个镜像,现在我们通过远程的 docker api 构建镜像,运行容器,发布镜像等操作. 这里只介绍两种方式: 远 ...
- 徒手撸一个 Spring Boot 中的 Starter ,解密自动化配置黑魔法!
我们使用 Spring Boot,基本上都是沉醉在它 Stater 的方便之中.Starter 为我们带来了众多的自动化配置,有了这些自动化配置,我们可以不费吹灰之力就能搭建一个生产级开发环境,有的小 ...
随机推荐
- 正则的使用及replace细讲
1.var reg=/./ 与 var reg=/\./的区别? .代表任意一个字符 \.而后者代表这个字符串中得有一个. 2.?的使用 如果单独的一个字符后面带? /\d?/ 代表1个或0个这个字符 ...
- Robot常用Library安装
Python-Library: yum install -y mysql-devel python-devel python-setuptools pip install MySQL-python p ...
- 1050 String Subtraction (20 分)
1050 String Subtraction (20 分) Given two strings S1 and S2, S=S1−S2 is defined to be the ...
- 3种方法轻松处理php开发中emoji表情的问题
背景 做微信开发的时候就会发现,存储微信昵称必不可少. 可这万恶的微信支持emoji表情做昵称,这就有点蛋疼了 一般Mysql表设计时,都是用UTF8字符集的.把带有emoji的昵称字段往里面inse ...
- STL容器能力一览表和各个容器操作函数异常保证
STL容器能力一览表 Vector Deque List Set Multiset map Multimap 典型内部 结构 dynamic array Array of arrays Doubly ...
- Sqoop+mysql+Hive+ Ozzie数据仓库案例
mysql 数据库脚本为: /*==============================================================*/ /* DBMS name: MySQL ...
- 写了个TP5下PHP和手机端通信的API接口校验
写了个PHP和手机端通信的API接口校验 直接发函数吧 public function _initialize() { //定义密码和盐 $password="123456"; $ ...
- Struts2:No result defined for action com.yibai.user.action.LoginAction and result input
转自:https://zhidao.baidu.com/question/133574016.html 1 String 里面有5个static 常量分别是: ERROR INPUT LOGIN NO ...
- Others-Goldengate 数据同步
GoldenGate 是一家创建于1995年的美国公司,开发总部设在旧金山,在北美,欧洲和亚洲(包括新加坡.印度.澳大利亚)设有支持中心. 公司名称 GoldenGate 总部地点 旧金山 成立时间 ...
- MVC中数据传递 ViewBag的使用
ViewBag MVC3中 ViewBag.ViewData和TempData的使用和差别 在MVC3開始.视图数据能够通过ViewBag属性訪问.在MVC2中则是使用ViewData.MVC3中保留 ...