SpringBoot集成WebSocket

 

1、pom.xml

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

1、config类

@Configuration
public class WebSocketConfig {

    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }
}

 

3、WebSocketServer类,

@ServerEndpoint("/api/websocket/{sid}")这就是和前端对接的地址
/**
 * 注解是一个类层次的注解,它的功能主要是将目前的类定义成一个websocket服务器端,
 * * 注解的值将被用于监听用户连接的终端访问URL地址,客户端可以通过这个URL来连接到WebSocket服务器端
 */
@Component
@Service
@ServerEndpoint("/api/websocket/{sid}")
public class WebSocketServer {

    //静态变量,记录在线连接数
    private static int onlineCount = 0;

    //concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。
    private static CopyOnWriteArraySet<WebSocketServer> webSocketServers = new CopyOnWriteArraySet<>();

    //与某个客户端的连接会话,需要通过它来给客户端发送数据
    private Session session;

    //接收sid
    private String sid = "";

    @OnOpen
    public void OnOpen(Session session, @PathParam("sid") String sid) {
        this.session = session;
        webSocketServers.add(this);
        this.sid = sid;
        addOnlineCount();
        try {
            sendMessage("conn_message");
            System.out.println("有新的登录,账号 = " + sid + ",当前在线人数:" + getOnlineCount());
        } catch (Exception e) {
            System.out.println("websocket IO Exception");
            e.printStackTrace();
        }
    }


    @OnMessage
    public void OnMessage(String message, Session session) {
        System.out.println("收到来自sid = 【" + sid + "】的消息:" + message);
        for (WebSocketServer item : webSocketServers) {
            try {
                item.sendMessage(message);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    @OnClose
    public void OnClose() {
        webSocketServers.remove(this);
        subOnlineCount();
        System.out.println("sid=" + this.sid + " 用户已断开连接");
        System.out.println("当前在线人数:" + onlineCount);
    }

    @OnError
    public void OnError(Session session, Throwable e) {
        System.out.println(session.getBasicRemote() + "发生异常.....");
        e.printStackTrace();
    }


    /**
     * 群发自定义消息
     *
     * @param message
     * @param sid
     */
    public static void sendInfo(String message, String sid) {
        System.out.println("sid= [" + sid + "]推送消息到窗口,消息:" + message);
        for (WebSocketServer item : webSocketServers) {
            try {
                if (sid == null) {
                    item.sendMessage(message);
                } else if (item.sid.equals(sid)) {
                    item.sendMessage(message);
                }
            } catch (IOException e) {
                continue;
            }
        }
    }

    /**
     * 实现服务器主动推送
     *
     * @param message
     * @throws IOException
     */
    public void sendMessage(String message) throws IOException {
        this.session.getBasicRemote().sendText(message);
    }

    public static synchronized int getOnlineCount() {
        return onlineCount;
    }

    public static synchronized void addOnlineCount() {
        WebSocketServer.onlineCount++;
    }

    public static synchronized void subOnlineCount() {
        WebSocketServer.onlineCount--;
    }

    public static CopyOnWriteArraySet<WebSocketServer> getWebSocketServers() {
        return webSocketServers;
    }

}

4、简单写个前端测试一下

<!DOCTYPE html>
<html>

	<head>
		<meta charset="utf-8">
		<title>SpringBoot集成WebSocket</title>
		<script type="text/javascript" src="http://apps.bdimg.com/libs/jquery/2.1.1/jquery.min.js"></script>
	</head>

	<body>
		<div id="main" style="width: 1200px;"></div>
		Welcome<br/><input id="text" type="text" />
		<button onclick="send()">发送消息</button>
		<hr/>
		<button onclick="closeWebSocket()">关闭WebSocket连接</button>
		<hr/>
		<div id="message"></div>
	</body>
	<script type="text/javascript">
		var websocket = null;
		//判断当前浏览器是否支持WebSocket
		if('WebSocket' in window) {
			//改成你的地址
			websocket = new WebSocket("ws://localhost:8080/api/websocket/100");
		} else {
			alert('当前浏览器 Not support websocket')
		}

		//连接发生错误的回调方法
		websocket.onerror = function() {
			setMessageInnerHTML("WebSocket连接发生错误");
		};

		//连接成功建立的回调方法
		websocket.onopen = function() {
			setMessageInnerHTML("WebSocket连接成功");
		}
		//接收到消息的回调方法
		websocket.onmessage = function(event) {
			console.log(event);
			setMessageInnerHTML(event.data);
		}

		//连接关闭的回调方法
		websocket.onclose = function() {
			setMessageInnerHTML("WebSocket连接关闭");
		}

		//监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
		window.onbeforeunload = function() {
			closeWebSocket();
		}

		//将消息显示在网页上
		function setMessageInnerHTML(innerHTML) {
			document.getElementById('message').innerHTML += innerHTML + '<br/>';
		}

		//关闭WebSocket连接
		function closeWebSocket() {
			websocket.close();
		}

		//发送消息
		function send() {
			var sid = $(" #test ").val();
			var message = document.getElementById('text').value;
			websocket.send('{"msg":"' + message + '"}');
			setMessageInnerHTML(message + "");
		}
	</script>

</html>

开始测试......................................................

后台服务启动、前端页面访问。

测试1:在线人数统计

前端初始化连接:

后台日志:

 

 

多用户同时在线:

测试2:发送消息

测试3:后台推送消息给前端

@RestController
@RequestMapping("/api/socket")
public class SystemController {

    @GetMapping("/socker/push/{cid}/{message}")
    public Map pushToWeb(@PathVariable String cid, @PathVariable String message) {
        Map<String, Object> resultMap = new HashMap<>();
        WebSocketServer.sendInfo(message, cid);
        resultMap.put("code", cid);
        resultMap.put("msg", message);
        return resultMap;
    }
}

 

测试完毕~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值