spring集成webSocket实现服务端向前端推送消息
原文:https://blog.csdn.net/ya_nuo/article/details/79612158
spring集成webSocket实现服务端向前端推送消息
1、前端连接websocket代码
- <%@ page language="java" contentType="text/html; charset=UTF-8"
- pageEncoding="UTF-8"%>
- <!DOCTYPE html>
- <html>
- <head lang="en">
- <meta charset="UTF-8">
- <script src="http://cdn.sockjs.org/sockjs-0.3.min.js"></script>
- <link rel="stylesheet" href="//cdn.bootcss.com/bootstrap/3.3.5/css/bootstrap.min.css">
- <link rel="stylesheet" href="//cdn.bootcss.com/bootstrap/3.3.5/css/bootstrap-theme.min.css">
- <script src="//cdn.bootcss.com/jquery/1.11.3/jquery.min.js"></script>
- <script src="//cdn.bootcss.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
- <title>webSocket-用户66</title>
- <script type="text/javascript">
- $(function() {
- var websocket;
- if('WebSocket' in window) {
- console.log("此浏览器支持websocket");
- websocket = new WebSocket("ws://localhost:8080/residential/websocketDemo/66");
- } else if('MozWebSocket' in window) {
- alert("此浏览器只支持MozWebSocket");
- } else {
- alert("此浏览器只支持SockJS");
- }
- websocket.onopen = function(evnt) {
- console.log(evnt);
- $("#tou").html("链接服务器成功!")
- };
- websocket.onmessage = function(evnt) {
- $("#msg").html($("#msg").html() + "<br/>" + evnt.data);
- };
- websocket.onerror = function(evnt) {};
- websocket.onclose = function(evnt) {
- console.log("与服务器断开了链接!");
- $("#tou").html("与服务器断开了链接!")
- }
- $('#close').bind('click', function() {
- websocket.close();
- });
- $('#send').bind('click', function() {
- send();
- });
- function send() {
- if(websocket != null) {
- var message = document.getElementById('message').value;
- console.log(message);
- websocket.send(message);
- } else {
- alert('未与服务器链接.');
- }
- }
- });
- </script>
- </head>
- <body>
- <div class="page-header" id="tou">
- webSocket多终端聊天测试
- </div>
- <div class="well" id="msg"></div>
- <div class="col-lg">
- <div class="input-group">
- <input type="text" class="form-control" placeholder="发送信息..." id="message">
- <span class="input-group-btn">
- <button class="btn btn-default" type="button" id="send" >发送</button>
- </span>
- </div>
- </div>
- <div>
- <button class="btn btn-default" type="button" id="close" >关闭连接</button>
- </div>
- </body>
- </html>
2、maven中导入SpringConfiguator的包
- <!-- websocket -->
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-websocket</artifactId>
- <version>${spring.version}</version>
- </dependency>
3、服务端连接websocket代码
- package org.property.component;
- import java.io.IOException;
- import java.util.HashMap;
- import java.util.HashSet;
- import java.util.Map;
- import java.util.Set;
- import javax.websocket.OnClose;
- import javax.websocket.OnError;
- import javax.websocket.OnMessage;
- import javax.websocket.OnOpen;
- import javax.websocket.Session;
- import javax.websocket.server.PathParam;
- import javax.websocket.server.ServerEndpoint;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- import org.springframework.web.socket.server.standard.SpringConfigurator;
- /**
- *
- * @Description: 给所用户所有终端推送消息
- * @author liuqin
- * @date 2018年3月19日 下午3:21:31
- *
- */
- //websocket连接URL地址和可被调用配置
- @ServerEndpoint(value="/websocketDemo/{userId}",configurator = SpringConfigurator.class)
- public class WebsocketDemo {
- //日志记录
- private Logger logger = LoggerFactory.getLogger(WebsocketDemo.class);
- //静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
- private static int onlineCount = 0;
- //记录每个用户下多个终端的连接
- private static Map<Long, Set<WebsocketDemo>> userSocket = new HashMap<>();
- //需要session来对用户发送数据, 获取连接特征userId
- private Session session;
- private Long userId;
- /**
- * @Title: onOpen
- * @Description: websocekt连接建立时的操作
- * @param @param userId 用户id
- * @param @param session websocket连接的session属性
- * @param @throws IOException
- */
- @OnOpen
- public void onOpen(@PathParam("userId") Long userId,Session session) throws IOException{
- this.session = session;
- this.userId = userId;
- onlineCount++;
- //根据该用户当前是否已经在别的终端登录进行添加操作
- if (userSocket.containsKey(this.userId)) {
- logger.debug("当前用户id:{}已有其他终端登录",this.userId);
- userSocket.get(this.userId).add(this); //增加该用户set中的连接实例
- }else {
- logger.debug("当前用户id:{}第一个终端登录",this.userId);
- Set<WebsocketDemo> addUserSet = new HashSet<>();
- addUserSet.add(this);
- userSocket.put(this.userId, addUserSet);
- }
- logger.info("用户{}登录的终端个数是为{}",userId,userSocket.get(this.userId).size());
- logger.info("当前在线用户数为:{},所有终端个数为:{}",userSocket.size(),onlineCount);
- }
- /**
- * @Title: onClose
- * @Description: 连接关闭的操作
- */
- @OnClose
- public void onClose(){
- onlineCount--;
- //移除当前用户终端登录的websocket信息,如果该用户的所有终端都下线了,则删除该用户的记录
- if (userSocket.get(this.userId).size() == 0) {
- userSocket.remove(this.userId);
- }else{
- userSocket.get(this.userId).remove(this);
- }
- logger.info("用户{}登录的终端个数是为{}",this.userId,userSocket.get(this.userId).size());
- logger.info("当前在线用户数为:{},所有终端个数为:{}",userSocket.size(),onlineCount);
- }
- /**
- * @Title: onMessage
- * @Description: 收到消息后的操作
- * @param @param message 收到的消息
- * @param @param session 该连接的session属性
- */
- @OnMessage
- public void onMessage(String message, Session session) {
- logger.info("收到来自用户id为:{}的消息:{}",this.userId,message);
- if(session ==null) logger.info("session null");
- }
- /**
- * @Title: onError
- * @Description: 连接发生错误时候的操作
- * @param @param session 该连接的session
- * @param @param error 发生的错误
- */
- @OnError
- public void onError(Session session, Throwable error){
- logger.debug("用户id为:{}的连接发送错误",this.userId);
- error.printStackTrace();
- }
- /**
- * @Title: sendMessageToUser
- * @Description: 发送消息给用户下的所有终端
- * @param @param userId 用户id
- * @param @param message 发送的消息
- * @param @return 发送成功返回true,反则返回false
- */
- public Boolean sendMessageToUser(Long userId,String message){
- if (userSocket.containsKey(userId)) {
- logger.info(" 给用户id为:{}的所有终端发送消息:{}",userId,message);
- for (WebsocketDemo WS : userSocket.get(userId)) {
- logger.info("sessionId为:{}",WS.session.getId());
- try {
- WS.session.getBasicRemote().sendText(message);
- } catch (IOException e) {
- e.printStackTrace();
- logger.info(" 给用户id为:{}发送消息失败",userId);
- return false;
- }
- }
- return true;
- }
- logger.info("发送错误:当前连接不包含id为:{}的用户",userId);
- return false;
- }
- }
4、Controller层发送消息方法
- package org.property.controller.property;
- import java.io.IOException;
- import javax.websocket.Session;
- import org.property.controller.BaseController;
- import org.property.service.WSMessageService;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.stereotype.Controller;
- import org.springframework.web.bind.annotation.RequestMapping;
- import org.springframework.web.bind.annotation.RequestMethod;
- import org.springframework.web.bind.annotation.RequestParam;
- import org.springframework.web.bind.annotation.ResponseBody;
- import org.springframework.web.servlet.ModelAndView;
- @Controller
- @RequestMapping("/message")
- public class MessageController extends BaseController{
- private static final Logger logger = LoggerFactory.getLogger(MessageController.class);
- //websocket服务层调用类
- @Autowired
- private WSMessageService wsMessageService;
- //请求入口
- @RequestMapping(value="/TestWS",method=RequestMethod.GET)
- @ResponseBody
- public String TestWS(@RequestParam(value="userId",required=true) Long userId,
- @RequestParam(value="message",required=true) String message){
- logger.debug("收到发送请求,向用户{}的消息:{}",userId,message);
- if(wsMessageService.sendToAllTerminal(userId, message)){
- return "发送成功";
- }else{
- return "发送失败";
- }
- }
- @RequestMapping(value="/test66",method=RequestMethod.GET)
- public ModelAndView test66() throws IOException{
- return new ModelAndView("/test", null);
- }
- @RequestMapping(value="/test88",method=RequestMethod.GET)
- public ModelAndView test88() throws IOException{
- return new ModelAndView("/test88", null);
- }
- }
5、service调用websocket发送消息
- package org.property.service;
- /**
- * @Class: WebSocketMessageService
- * @Description: 使用webscoket连接向用户发送信息
- * @author JFPZ
- * @date 2017年5月15日 上午20:17:01
- */
- import java.io.IOException;
- import javax.websocket.Session;
- import org.property.component.WebsocketDemo;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- import org.springframework.stereotype.Service;
- @Service("webSocketMessageService")
- public class WSMessageService {
- private Logger logger = LoggerFactory.getLogger(WSMessageService.class);
- //声明websocket连接类
- private WebsocketDemo websocketDemo = new WebsocketDemo();
- /**
- * @Title: sendToAllTerminal
- * @Description: 调用websocket类给用户下的所有终端发送消息
- * @param @param userId 用户id
- * @param @param message 消息
- * @param @return 发送成功返回true,否则返回false
- */
- public Boolean sendToAllTerminal(Long userId,String message){
- logger.info("向用户{}的消息:{}",userId,message);
- if(websocketDemo.sendMessageToUser(userId,message)){
- return true;
- }else{
- return false;
- }
- }
- }
6、测试,连接发送成功。
spring集成webSocket实现服务端向前端推送消息的更多相关文章
- SpringBoot2.0集成WebSocket,实现后台向前端推送信息
感谢作者,支持原创: https://blog.csdn.net/moshowgame/article/details/80275084 什么是WebSocket? WebSocket协议是基于TCP ...
- 服务端向客户端推送消息技术之websocket的介绍
websocket的介绍 在讲解WebSocket前,我们先来看看下面这种场景,在HTTP协议下,怎么实现. 需求: 在网站中,要实现简单的聊天,这种情况怎么实现呢?如下图: 当发送私信的时候,如果要 ...
- Spring Boot 集成 WebSocket 实现服务端推送消息到客户端
假设有这样一个场景:服务端的资源经常在更新,客户端需要尽量及时地了解到这些更新发生后展示给用户,如果是 HTTP 1.1,通常会开启 ajax 请求询问服务端是否有更新,通过定时器反复轮询服务端响应的 ...
- C#服务端通过Socket推送数据到Android端App中
需求: 描述:实时在客户端上获取到哪些款需要补货. 要求: 后台需要使用c#,并且哪些需要补货的逻辑写在公司框架内,客户端采用PDA(即Android客户端 版本4.4) . 用户打开了补货通知页面时 ...
- Java端百度云推送消息Demo
因为在做Java服务器有用到推送消息机制,于是到网上找了一下,就自己试着敲了一个demo.这个demo主要是简单的一个对app消息推送. jar:百度云消息推送Java端的jar. package x ...
- java服务端的 极光推送
项目中用到了极光推送 下面写下笔记 首先引入jar包 下载地址https://docs.jiguang.cn/jpush/resources/(非maven项目的下载地址) <depend ...
- 结合实际需求,在webapi内利用WebSocket建立单向的消息推送平台,让A页面和服务端建立WebSocket连接,让其他页面可以及时给A页面推送消息
1.需求示意图 2.需求描述 原本是为了给做unity3d客户端开发的同事提供不定时的消息推送,比如商城购买道具后服务端将道具信息推送给客户端. 本篇文章简化理解,用“相关部门开展活动,向全市人民征集 ...
- 使用WebSocket实现服务端和客户端的通信
开发中经常会有这样的使用场景.如某个用户在一个数据上做了xx操作, 与该数据相关的用户在线上的话,需要实时接收到一条信息. 这种可以使用WebSocket来实现. 另外,对于消息,可以定义一个类进行固 ...
- springboot 服务端获取前端传过来的参数7种方式
下面为7种服务端获取前端传过来的参数的方法 1.直接把表单的参数写在Controller相应的方法的形参中,适用于GET 和 POST请求方式 这种方式不会校验请求里是否带参数,即下面的userna ...
随机推荐
- [T-ARA][HUE]
歌词来源:http://music.163.com/#/song?id=22704406 wa du seu mo geum to yo do ga tae 어딜가도 스페셜한게 없어 [eo-dil ...
- Full Binary Tree(二叉树找规律)
Description In computer science, a binary tree is a tree data structure in which each node has at mo ...
- OpenNF tutorial复现
这篇博客记录了自己实现OpenNF官网上tutorial的过程和遇见的问题,如果有不对的地方还请批评指正! tutorial链接 实验内容 这个实验展示了如何迅速且安全地把一个TCP流从一个NF实例迁 ...
- 博弈---威佐夫博奕(Wythoff Game)
这个写的不错 威佐夫博奕(Wythoff Game):有两堆各若干个物品,两个人轮流从某一堆或同 时从两堆中取同样多的物品,规定每次至少取一个,多者不限,最后取光者得胜. 这种情况下是颇为复杂 ...
- erlang调优方法
1. 来自Scaling Erlang的方法 内核调优: # Increase the ipv4 port range: sysctl -w net.ipv4.ip_local_port_range= ...
- 移植spdylay到libcurl
Libcurl是第三方网络库,支持各种网络协议 SPDY是Google提出的用来替代HTTP1.1的网络协议, 目前google.com, facebook.com, twitter.com服务器端都 ...
- Spring学习 6- Spring MVC (Spring MVC原理及配置详解)
百度的面试官问:Web容器,Servlet容器,SpringMVC容器的区别: 我还写了个文章,说明web容器与servlet容器的联系,参考:servlet单实例多线程模式 这个文章有web容器与s ...
- 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 ...
- MVC 中创建简单过滤器
1.新建一个类,继承自 ActionFilterAttribute类,并重写OnActionExecuting()方法 public class LoginFilter:ActionFilterAtt ...
- python的N个小功能之正则匹配
1.. 匹配任意除换行符“\n”外的字符:2.*表示匹配前一个字符0次或无限次:3.+或*后跟?表示非贪婪匹配,即尽可能少的匹配,如*?重复任意次,但尽可能少重复,惰性匹配:4. .*? 表示匹配任意 ...