<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>

一:先导入上面的jar

二:放入websocket 相关配置代码

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; /**
* 因为WebSocket是类似客户端服务端的形式(采用ws协议),那么这里的WebSocketServer其实就相当于一个ws协议的Controller
* 直接@ServerEndpoint("/websocket")@Component启用即可,然后在里面实现@OnOpen,@onClose,@onMessage等方法
*
* @author Admin
*/
@ServerEndpoint("/shdxmh/websocket/{deptId}")
@Component
@RestController
public class WebSocketAction { private static Logger logger = LoggerFactory.getLogger(WebSocketAction.class); /**
* 静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
*/
private static int onlineCount = 0; /**
* concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。
*/
private static CopyOnWriteArraySet<WebSocketAction> webSocketSet = new CopyOnWriteArraySet<WebSocketAction>(); /**
* 与某个客户端的连接会话,需要通过它来给客户端发送数据
*/
private Session session; /**
* 接收sid
*/
private String deptId = ""; private static ExecutorService executorService = Executors.newFixedThreadPool(10); /**
* 连接建立成功调用的方法
*
* @param deptId 唯一性ID
* @param session socket session
* @return void
*/
@OnOpen
public void onOpen(@PathParam("deptId") String deptId, Session session) {
this.session = session;
//加入set中
webSocketSet.add(this); //添加在线人数
addOnlineCount();
this.deptId = deptId;
// logger.info("新连接接入,deptId={}, sessionId={}, 当前在线人数为:{}", this.deptId, session.getId(), getOnlineCount());
} /**
* 连接关闭调用的方法
*/
@OnClose
public void onClose(Session session) {
//从set中删除
webSocketSet.remove(this);
//在线数减1
subOnlineCount();
// logger.info("有连接关闭, sessionId={}。当前在线人数为:{}", session.getId(), getOnlineCount());
} /**
* 暴露给外部的群发
*
* @param message
* @throws IOException
*/
@RequestMapping("/websocket-send")
public static void sendInfo(String message, @PathParam("deptId") String deptId) {
executorService.execute(() -> {
logger.info("推送消息到窗口" + deptId + ",推送内容:" + message);
for (WebSocketAction item : webSocketSet) {
try {
//这里可以设定只推送给这个sid的,为null则全部推送
if (deptId == null) {
item.sendMessage(message);
}
//点对点推送
else if (item.deptId.equals(deptId)) {
item.sendMessage(message);
}
} catch (IOException e) {
logger.error("推送异常", e);
}
}
});
} /**
* 群发
*
* @param message
*/
private static void sendAll(String message) { for (WebSocketAction webSocketAction : webSocketSet) {
try {
webSocketAction.sendMessage(message);
} catch (IOException e) {
logger.error("群发异常", e);
}
}
} /**
* 发生错误时调用
*
* @param session
* @param error
*/
@OnError
public void onError(Session session, Throwable error) {
logger.error("websocket异常, sessionId={}",session.getId(), error);
} /**
* 减少在线人数
*/
private synchronized static void subOnlineCount() {
WebSocketAction.onlineCount--;
} /**
* 添加在线人数
*/
private synchronized static void addOnlineCount() {
WebSocketAction.onlineCount++;
} /**
* 当前在线人数
*
* @return 在线人数
*/
public int getOnlineCount() {
return onlineCount;
} /**
* 发送信息实现服务器主动推送信息
*
* @param message
* @throws IOException
*/
public void sendMessage(String message) throws IOException {
// logger.info("发送消息, message={}", message);
//获取session远程基本连接发送文本消息
// tomcat有bug, 多个线程向一个socket写数据会冲突 报IllegalStateException...[TEXT_FULL_WRITING], 故此处加锁和使用getBasicRemote
synchronized (this.session) {
this.session.getBasicRemote().sendText(message);
}
// session.getAsyncRemote().sendText(message); } /**
* 群发
*南桥引入
* @param message
*/
public static void sendAllMsg(String message) { for (WebSocketAction webSocketAction : webSocketSet) {
try {
webSocketAction.sendMessage(message);
} catch (IOException e) {
logger.error("群发异常", e);
}
}
} }

三:浏览器连上websocket 充当客户端

四:postman 调用后台接口发送信息

完活!其他方法自己看。

java websocket详细的更多相关文章

  1. Java log4j详细教程

    Java log4j详细教程 http://www.jb51.net/article/74475.htm

  2. 使用Jetty搭建Java Websocket Server,实现图像传输

    https://my.oschina.net/yushulx/blog/298140 How to Implement a Java WebSocket Server for Image Transm ...

  3. Java WebSocket 线程安全的保证

    Java WebSocket线程安全基于3点: 1 在新的客户端连接时,WebSocket容器会创建一个新的端点实例,对应的会话实例表示从唯一的客户端到该端点实例的唯一连接. 2 每个WebSocke ...

  4. Java WebSocket HttpSession与WebSocket Session的关联

    当HttpSession中止(通过显示地失效或超时)时,Web容器会把HttpSession属性从HttpSession中清除. javax.servlet.http.HttpSessionBindi ...

  5. java websocket学习

    引言: websocket,webservice傻傻分不清楚,都觉得是很高深的东西,理解中的webservice是一种协议,通信协议,类似http协议的那种,比如使用webservice协议调后台接口 ...

  6. java websocket开发的客户端程序

    最近用java websocket开发的客户端程序,在和服务端链接通后,在数据传输完毕后,客户端自动关闭了链接,如何能保持链接不断开 这个是客户端的启动类,在循环完毕后,会自动断开和服务器的链接,开始 ...

  7. java agent 详细介绍 -javaagent参数

    java agent 详细介绍 简介 java agent是java命令的一个参数.参数 javaagent 可以用于指定一个 jar 包,并且对该 java 包有2个要求: 这个 jar 包的MAN ...

  8. java WebSocket Demo

    1.IDEA创建Module,结构如图(Tomcat8.0) 2.引入jar包:javax.websocket-api.jar 3.新建WebSocketTest类 import javax.webs ...

  9. JAVA HashMap详细介绍和示例

    http://www.jb51.net/article/42769.htm 我们先对HashMap有个整体认识,然后再学习它的源码,最后再通过实例来学会使用HashMap.   第1部分 HashMa ...

  10. Java EL 详细用法讲解

    本文主要介绍了Java EL的语法结构以及EL的使用方法,并结合例子代码讲解了Java EL对象.Java EL运算符以及Java EL函数.希望对Java开发者有所帮助. 一.EL简介 1.语法结构 ...

随机推荐

  1. Java设计模式——装饰器模式(Decorator)

    今天上课讲了java设计模式中的装饰器模式--Decorator,由于早上起的很早,肚子也很饿,知识点本身也晦涩难懂,听的云里雾里的,所以在课下对这块的知识做出一些总结. 定义 装饰器模式又名包装(W ...

  2. Vue I18n Vue.js 的国际化插件+elementUI的使用

    先附上插件官网 vue-i18n中文官网 我们的vue项目需要支持多语言时,可以使用这个插件 安装插件教程在官网可以找到 代码结构可以如下 zh.js 查看代码 export default { lo ...

  3. SDN第二次实验

    一.实验目的能够对Open vSwitch进行基本操作:能够通过命令行终端使用OVS命令操作Open vSwitch交换机,管理流表:能够通过Mininet的Python代码运行OVS命令,控制网络拓 ...

  4. Flutter tab切换保持页面状态的两种方法

    当通过底部tabBar将页面在"首页"和"分类"之间进行切换的时候,每一次进入页面的时候该页面的数据都会重新加载.那么如何让页面保持原来的状态,而不是每次都要重 ...

  5. KingbaseES V8R3集群运维案例之---kingbase_monitor.sh启动”two master“案例

    案例说明: KingbaseES V8R3集群,执行kingbase_monitor.sh启动集群,出现"two master"节点的故障,启动集群失败:通过手工sys_ctl启动 ...

  6. SQL开窗函数用法

    开窗函数分类: 根据使用的目的,开窗函数可以分为两类:聚合开窗函数和排序开窗函数. 下面主要解析四种常用的排序开窗函数: 1.ROW_NUMBER() OVER () : 对相等的值不进行区分,序号连 ...

  7. Visual Studio 快速生成构造函数

    生成构造函数快速操作 - Visual Studio (Windows) | Microsoft Learn 键盘 按 (Ctrl+.) 触发"快速操作和重构"菜单. 鼠标 右键单 ...

  8. django 关联类 DoesNotExist: User matching query does not exist.

    问题就是 关联类为空找不到 在或者geattr / hasattr / obj. item 会抛出异常 无法通过判断处理 捕获异常 try: tmp_data['demand_dept_name'] ...

  9. IMX6Ull驱动

    mount -t nfs -o nolock,vers=3 192.168.1.117:/home/book/nfs_rootfs /mnt cat /proc/sys/kernel/printk e ...

  10. twenty two

    打包处理less文件 1,运行npm i less-loader@10.0.1 less@4.1.1 -D 2, 在webpack.config.js的module->rules数组中 rule ...