原文:https://blog.csdn.net/ya_nuo/article/details/79612158

spring集成webSocket实现服务端向前端推送消息

 

1、前端连接websocket代码

  1. <%@ page language="java" contentType="text/html; charset=UTF-8"
  2. pageEncoding="UTF-8"%>
  3. <!DOCTYPE html>
  4. <html>
  5.  
  6. <head lang="en">
  7. <meta charset="UTF-8">
  8. <script src="http://cdn.sockjs.org/sockjs-0.3.min.js"></script>
  9. <link rel="stylesheet" href="//cdn.bootcss.com/bootstrap/3.3.5/css/bootstrap.min.css">
  10. <link rel="stylesheet" href="//cdn.bootcss.com/bootstrap/3.3.5/css/bootstrap-theme.min.css">
  11. <script src="//cdn.bootcss.com/jquery/1.11.3/jquery.min.js"></script>
  12. <script src="//cdn.bootcss.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
  13. <title>webSocket-用户66</title>
  14. <script type="text/javascript">
  15. $(function() {
  16. var websocket;
  17. if('WebSocket' in window) {
  18. console.log("此浏览器支持websocket");
  19. websocket = new WebSocket("ws://localhost:8080/residential/websocketDemo/66");
  20. } else if('MozWebSocket' in window) {
  21. alert("此浏览器只支持MozWebSocket");
  22. } else {
  23. alert("此浏览器只支持SockJS");
  24. }
  25. websocket.onopen = function(evnt) {
  26. console.log(evnt);
  27. $("#tou").html("链接服务器成功!")
  28. };
  29. websocket.onmessage = function(evnt) {
  30. $("#msg").html($("#msg").html() + "<br/>" + evnt.data);
  31. };
  32. websocket.onerror = function(evnt) {};
  33. websocket.onclose = function(evnt) {
  34. console.log("与服务器断开了链接!");
  35. $("#tou").html("与服务器断开了链接!")
  36. }
  37.  
  38. $('#close').bind('click', function() {
  39. websocket.close();
  40. });
  41.  
  42. $('#send').bind('click', function() {
  43. send();
  44. });
  45.  
  46. function send() {
  47. if(websocket != null) {
  48. var message = document.getElementById('message').value;
  49. console.log(message);
  50. websocket.send(message);
  51. } else {
  52. alert('未与服务器链接.');
  53. }
  54. }
  55. });
  56. </script>
  57. </head>
  58.  
  59. <body>
  60. <div class="page-header" id="tou">
  61. webSocket多终端聊天测试
  62. </div>
  63. <div class="well" id="msg"></div>
  64. <div class="col-lg">
  65. <div class="input-group">
  66. <input type="text" class="form-control" placeholder="发送信息..." id="message">
  67. <span class="input-group-btn">
  68. <button class="btn btn-default" type="button" id="send" >发送</button>
  69. </span>
  70. </div>
  71. </div>
  72. <div>
  73. <button class="btn btn-default" type="button" id="close" >关闭连接</button>
  74. </div>
  75. </body>
  76. </html>

2、maven中导入SpringConfiguator的包

  1. <!-- websocket -->
  2. <dependency>
  3. <groupId>org.springframework</groupId>
  4. <artifactId>spring-websocket</artifactId>
  5. <version>${spring.version}</version>
  6. </dependency>

3、服务端连接websocket代码

  1. package org.property.component;
  2.  
  3. import java.io.IOException;
  4. import java.util.HashMap;
  5. import java.util.HashSet;
  6. import java.util.Map;
  7. import java.util.Set;
  8.  
  9. import javax.websocket.OnClose;
  10. import javax.websocket.OnError;
  11. import javax.websocket.OnMessage;
  12. import javax.websocket.OnOpen;
  13. import javax.websocket.Session;
  14. import javax.websocket.server.PathParam;
  15. import javax.websocket.server.ServerEndpoint;
  16.  
  17. import org.slf4j.Logger;
  18. import org.slf4j.LoggerFactory;
  19. import org.springframework.web.socket.server.standard.SpringConfigurator;
  20.  
  21. /**
  22. *
  23. * @Description: 给所用户所有终端推送消息
  24. * @author liuqin
  25. * @date 2018年3月19日 下午3:21:31
  26. *
  27. */
  28. //websocket连接URL地址和可被调用配置
  29. @ServerEndpoint(value="/websocketDemo/{userId}",configurator = SpringConfigurator.class)
  30. public class WebsocketDemo {
  31. //日志记录
  32. private Logger logger = LoggerFactory.getLogger(WebsocketDemo.class);
  33. //静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
  34. private static int onlineCount = 0;
  35.  
  36. //记录每个用户下多个终端的连接
  37. private static Map<Long, Set<WebsocketDemo>> userSocket = new HashMap<>();
  38.  
  39. //需要session来对用户发送数据, 获取连接特征userId
  40. private Session session;
  41. private Long userId;
  42.  
  43. /**
  44. * @Title: onOpen
  45. * @Description: websocekt连接建立时的操作
  46. * @param @param userId 用户id
  47. * @param @param session websocket连接的session属性
  48. * @param @throws IOException
  49. */
  50. @OnOpen
  51. public void onOpen(@PathParam("userId") Long userId,Session session) throws IOException{
  52. this.session = session;
  53. this.userId = userId;
  54. onlineCount++;
  55. //根据该用户当前是否已经在别的终端登录进行添加操作
  56. if (userSocket.containsKey(this.userId)) {
  57. logger.debug("当前用户id:{}已有其他终端登录",this.userId);
  58. userSocket.get(this.userId).add(this); //增加该用户set中的连接实例
  59. }else {
  60. logger.debug("当前用户id:{}第一个终端登录",this.userId);
  61. Set<WebsocketDemo> addUserSet = new HashSet<>();
  62. addUserSet.add(this);
  63. userSocket.put(this.userId, addUserSet);
  64. }
  65. logger.info("用户{}登录的终端个数是为{}",userId,userSocket.get(this.userId).size());
  66. logger.info("当前在线用户数为:{},所有终端个数为:{}",userSocket.size(),onlineCount);
  67. }
  68.  
  69. /**
  70. * @Title: onClose
  71. * @Description: 连接关闭的操作
  72. */
  73. @OnClose
  74. public void onClose(){
  75. onlineCount--;
  76. //移除当前用户终端登录的websocket信息,如果该用户的所有终端都下线了,则删除该用户的记录
  77. if (userSocket.get(this.userId).size() == 0) {
  78. userSocket.remove(this.userId);
  79. }else{
  80. userSocket.get(this.userId).remove(this);
  81. }
  82. logger.info("用户{}登录的终端个数是为{}",this.userId,userSocket.get(this.userId).size());
  83. logger.info("当前在线用户数为:{},所有终端个数为:{}",userSocket.size(),onlineCount);
  84. }
  85.  
  86. /**
  87. * @Title: onMessage
  88. * @Description: 收到消息后的操作
  89. * @param @param message 收到的消息
  90. * @param @param session 该连接的session属性
  91. */
  92. @OnMessage
  93. public void onMessage(String message, Session session) {
  94. logger.info("收到来自用户id为:{}的消息:{}",this.userId,message);
  95. if(session ==null) logger.info("session null");
  96. }
  97.  
  98. /**
  99. * @Title: onError
  100. * @Description: 连接发生错误时候的操作
  101. * @param @param session 该连接的session
  102. * @param @param error 发生的错误
  103. */
  104. @OnError
  105. public void onError(Session session, Throwable error){
  106. logger.debug("用户id为:{}的连接发送错误",this.userId);
  107. error.printStackTrace();
  108. }
  109.  
  110. /**
  111. * @Title: sendMessageToUser
  112. * @Description: 发送消息给用户下的所有终端
  113. * @param @param userId 用户id
  114. * @param @param message 发送的消息
  115. * @param @return 发送成功返回true,反则返回false
  116. */
  117. public Boolean sendMessageToUser(Long userId,String message){
  118. if (userSocket.containsKey(userId)) {
  119. logger.info(" 给用户id为:{}的所有终端发送消息:{}",userId,message);
  120. for (WebsocketDemo WS : userSocket.get(userId)) {
  121. logger.info("sessionId为:{}",WS.session.getId());
  122. try {
  123. WS.session.getBasicRemote().sendText(message);
  124. } catch (IOException e) {
  125. e.printStackTrace();
  126. logger.info(" 给用户id为:{}发送消息失败",userId);
  127. return false;
  128. }
  129. }
  130. return true;
  131. }
  132. logger.info("发送错误:当前连接不包含id为:{}的用户",userId);
  133. return false;
  134. }
  135.  
  136. }

4、Controller层发送消息方法

  1. package org.property.controller.property;
  2. import java.io.IOException;
  3.  
  4. import javax.websocket.Session;
  5.  
  6. import org.property.controller.BaseController;
  7. import org.property.service.WSMessageService;
  8. import org.slf4j.Logger;
  9. import org.slf4j.LoggerFactory;
  10. import org.springframework.beans.factory.annotation.Autowired;
  11. import org.springframework.stereotype.Controller;
  12. import org.springframework.web.bind.annotation.RequestMapping;
  13. import org.springframework.web.bind.annotation.RequestMethod;
  14. import org.springframework.web.bind.annotation.RequestParam;
  15. import org.springframework.web.bind.annotation.ResponseBody;
  16. import org.springframework.web.servlet.ModelAndView;
  17.  
  18. @Controller
  19. @RequestMapping("/message")
  20. public class MessageController extends BaseController{
  21. private static final Logger logger = LoggerFactory.getLogger(MessageController.class);
  22. //websocket服务层调用类
  23. @Autowired
  24. private WSMessageService wsMessageService;
  25.  
  26. //请求入口
  27. @RequestMapping(value="/TestWS",method=RequestMethod.GET)
  28. @ResponseBody
  29. public String TestWS(@RequestParam(value="userId",required=true) Long userId,
  30. @RequestParam(value="message",required=true) String message){
  31. logger.debug("收到发送请求,向用户{}的消息:{}",userId,message);
  32. if(wsMessageService.sendToAllTerminal(userId, message)){
  33. return "发送成功";
  34. }else{
  35. return "发送失败";
  36. }
  37. }
  38.  
  39. @RequestMapping(value="/test66",method=RequestMethod.GET)
  40. public ModelAndView test66() throws IOException{
  41. return new ModelAndView("/test", null);
  42. }
  43.  
  44. @RequestMapping(value="/test88",method=RequestMethod.GET)
  45. public ModelAndView test88() throws IOException{
  46. return new ModelAndView("/test88", null);
  47. }
  48. }

5、service调用websocket发送消息

  1. package org.property.service;
  2. /**
  3. * @Class: WebSocketMessageService
  4. * @Description: 使用webscoket连接向用户发送信息
  5. * @author JFPZ
  6. * @date 2017年5月15日 上午20:17:01
  7. */
  8. import java.io.IOException;
  9.  
  10. import javax.websocket.Session;
  11.  
  12. import org.property.component.WebsocketDemo;
  13. import org.slf4j.Logger;
  14. import org.slf4j.LoggerFactory;
  15. import org.springframework.stereotype.Service;
  16.  
  17. @Service("webSocketMessageService")
  18. public class WSMessageService {
  19. private Logger logger = LoggerFactory.getLogger(WSMessageService.class);
  20. //声明websocket连接类
  21. private WebsocketDemo websocketDemo = new WebsocketDemo();
  22.  
  23. /**
  24. * @Title: sendToAllTerminal
  25. * @Description: 调用websocket类给用户下的所有终端发送消息
  26. * @param @param userId 用户id
  27. * @param @param message 消息
  28. * @param @return 发送成功返回true,否则返回false
  29. */
  30. public Boolean sendToAllTerminal(Long userId,String message){
  31. logger.info("向用户{}的消息:{}",userId,message);
  32. if(websocketDemo.sendMessageToUser(userId,message)){
  33. return true;
  34. }else{
  35. return false;
  36. }
  37. }
  38.  
  39. }

6、测试,连接发送成功。

spring集成webSocket实现服务端向前端推送消息的更多相关文章

  1. SpringBoot2.0集成WebSocket,实现后台向前端推送信息

    感谢作者,支持原创: https://blog.csdn.net/moshowgame/article/details/80275084 什么是WebSocket? WebSocket协议是基于TCP ...

  2. 服务端向客户端推送消息技术之websocket的介绍

    websocket的介绍 在讲解WebSocket前,我们先来看看下面这种场景,在HTTP协议下,怎么实现. 需求: 在网站中,要实现简单的聊天,这种情况怎么实现呢?如下图: 当发送私信的时候,如果要 ...

  3. Spring Boot 集成 WebSocket 实现服务端推送消息到客户端

    假设有这样一个场景:服务端的资源经常在更新,客户端需要尽量及时地了解到这些更新发生后展示给用户,如果是 HTTP 1.1,通常会开启 ajax 请求询问服务端是否有更新,通过定时器反复轮询服务端响应的 ...

  4. C#服务端通过Socket推送数据到Android端App中

    需求: 描述:实时在客户端上获取到哪些款需要补货. 要求: 后台需要使用c#,并且哪些需要补货的逻辑写在公司框架内,客户端采用PDA(即Android客户端 版本4.4) . 用户打开了补货通知页面时 ...

  5. Java端百度云推送消息Demo

    因为在做Java服务器有用到推送消息机制,于是到网上找了一下,就自己试着敲了一个demo.这个demo主要是简单的一个对app消息推送. jar:百度云消息推送Java端的jar. package x ...

  6. java服务端的 极光推送

    项目中用到了极光推送  下面写下笔记 首先引入jar包   下载地址https://docs.jiguang.cn/jpush/resources/(非maven项目的下载地址) <depend ...

  7. 结合实际需求,在webapi内利用WebSocket建立单向的消息推送平台,让A页面和服务端建立WebSocket连接,让其他页面可以及时给A页面推送消息

    1.需求示意图 2.需求描述 原本是为了给做unity3d客户端开发的同事提供不定时的消息推送,比如商城购买道具后服务端将道具信息推送给客户端. 本篇文章简化理解,用“相关部门开展活动,向全市人民征集 ...

  8. 使用WebSocket实现服务端和客户端的通信

    开发中经常会有这样的使用场景.如某个用户在一个数据上做了xx操作, 与该数据相关的用户在线上的话,需要实时接收到一条信息. 这种可以使用WebSocket来实现. 另外,对于消息,可以定义一个类进行固 ...

  9. springboot 服务端获取前端传过来的参数7种方式

    下面为7种服务端获取前端传过来的参数的方法  1.直接把表单的参数写在Controller相应的方法的形参中,适用于GET 和 POST请求方式 这种方式不会校验请求里是否带参数,即下面的userna ...

随机推荐

  1. [T-ARA][HUE]

    歌词来源:http://music.163.com/#/song?id=22704406 wa du seu mo geum to yo do ga tae 어딜가도 스페셜한게 없어 [eo-dil ...

  2. Full Binary Tree(二叉树找规律)

    Description In computer science, a binary tree is a tree data structure in which each node has at mo ...

  3. OpenNF tutorial复现

    这篇博客记录了自己实现OpenNF官网上tutorial的过程和遇见的问题,如果有不对的地方还请批评指正! tutorial链接 实验内容 这个实验展示了如何迅速且安全地把一个TCP流从一个NF实例迁 ...

  4. 博弈---威佐夫博奕(Wythoff Game)

    这个写的不错 威佐夫博奕(Wythoff Game):有两堆各若干个物品,两个人轮流从某一堆或同 时从两堆中取同样多的物品,规定每次至少取一个,多者不限,最后取光者得胜.     这种情况下是颇为复杂 ...

  5. erlang调优方法

    1. 来自Scaling Erlang的方法 内核调优: # Increase the ipv4 port range: sysctl -w net.ipv4.ip_local_port_range= ...

  6. 移植spdylay到libcurl

    Libcurl是第三方网络库,支持各种网络协议 SPDY是Google提出的用来替代HTTP1.1的网络协议, 目前google.com, facebook.com, twitter.com服务器端都 ...

  7. Spring学习 6- Spring MVC (Spring MVC原理及配置详解)

    百度的面试官问:Web容器,Servlet容器,SpringMVC容器的区别: 我还写了个文章,说明web容器与servlet容器的联系,参考:servlet单实例多线程模式 这个文章有web容器与s ...

  8. Bare metal APIs with ASP.NET Core MVC(转)

    ASP.NET Core MVC now provides a true "one asp.net" framework that can be used for building ...

  9. MVC 中创建简单过滤器

    1.新建一个类,继承自 ActionFilterAttribute类,并重写OnActionExecuting()方法 public class LoginFilter:ActionFilterAtt ...

  10. python的N个小功能之正则匹配

    1.. 匹配任意除换行符“\n”外的字符:2.*表示匹配前一个字符0次或无限次:3.+或*后跟?表示非贪婪匹配,即尽可能少的匹配,如*?重复任意次,但尽可能少重复,惰性匹配:4. .*? 表示匹配任意 ...