springboot实现服务器端消息推送(websocket + sockjs + stomp)

 

  服务器端推送技术在web开发中比较常用,可能早期很多人的解决方案是采用ajax向服务器轮询消息,这种方式的轮询频率不好控制,所以大大增加了服务器的压力,后来有了下面的方案:当客户端向服务器发送请求时,服务器端会抓住这个请求不放,等有数据更新的时候才返回给客户端,当客户端接收到数据后再次发送请求,周而复始,这样就大大减少了请求次数,减轻了服务器的压力,当前主要有SSE(Server Send Event 服务器端事件发送)的服务器端推送和基于Servlet3.0+异步方法特性实现的服务器端推送。而本次我将利用webSokcet实现服务器端消息推送。话不多说上代码:

  1、pom.xml,新建springboot项目,加入webSocket启动包spring-boot-starter-websocket;

  2、WebSocketConfig

package com.example.demo.websocket;

import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.AbstractWebSocketMessageBrokerConfigurer;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry; @Configuration
@EnableWebSocketMessageBroker //注解开启STOMP协议来传输基于代理的消息,此时控制器支持使用@MessageMapping
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer { @Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableSimpleBroker("/topic","/user");//topic用来广播,user用来实现p2p
} @Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/webServer").withSockJS();
registry.addEndpoint("/queueServer").withSockJS();//注册两个STOMP的endpoint,分别用于广播和点对点
} }

  3、接收消息类:ReceiveMessage

package com.example.demo.websocket;

public class ReceiveMessage {

    private String name;

    public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

  4、响应消息类:ResponseMessage

package com.example.demo.websocket;

public class ResponseMessage {

    private String id;
private String name;
private String content;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public ResponseMessage(String id, String name, String content) {
super();
this.id = id;
this.name = name;
this.content = content;
} }

  5、控制器类:SubController

package com.example.demo.websocket;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.stereotype.Controller; @Controller
public class SubController {
@Autowired
public SimpMessagingTemplate template; @MessageMapping("/subscribe")
public void subscribe(ReceiveMessage rm) {
for(int i =1;i<=20;i++) {
//广播使用convertAndSend方法,第一个参数为目的地,和js中订阅的目的地要一致
template.convertAndSend("/topic/getResponse", rm.getName());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
} } @MessageMapping("/queue")
public void queuw(ReceiveMessage rm) {
System.out.println("进入方法");
for(int i =1;i<=20;i++) {
/*广播使用convertAndSendToUser方法,第一个参数为用户id,此时js中的订阅地址为
"/user/" + 用户Id + "/message",其中"/user"是固定的*/
template.convertAndSendToUser("zhangsan","/message",rm.getName());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
} }
}

  6、在src/main/resource包下建一个static包,引入jquery-3.2.1.min.js、sock.js、stomp.js,创建topic.html和queue.html。

<html>
<head>
<meta charset="UTF-8">
<title>Hello topic</title>
<script src="sock.js"></script>
<script src="stomp.js"></script>
<script src="jquery-3.2.1.min.js"></script>
<script type="text/javascript">
var stompClient = null;
function setConnected(connected){
document.getElementById("connect").disabled = connected;
document.getElementById("disconnect").disabled = !connected;
$("#response").html();
}
function connect() {
var socket = new SockJS("/webServer");
stompClient = Stomp.over(socket);
stompClient.connect({}, function(frame) {
setConnected(true);
console.log('Connected: ' + frame);
stompClient.subscribe('/topic/getResponse', function(response){
var response1 = document.getElementById('response');
var p = document.createElement('p');
p.style.wordWrap = 'break-word';
p.appendChild(document.createTextNode(response.body));
response1.appendChild(p);
});
});
} function disconnect() {
if (stompClient != null) {
stompClient.disconnect();
}
setConnected(false);
console.log("Disconnected");
} function sendName() {
var name = document.getElementById('name').value;
console.info(1111111111);
stompClient.send("/subscribe", {}, JSON.stringify({ 'name': name }));
}
</script>
</head>
<body onload="disconnect()">
<noscript><h2 style="color: #ff0000">Seems your browser doesn't support Javascript! Websocket relies on Javascript being enabled. Please enable
Javascript and reload this page!</h2></noscript>
<div>
<div>
<button id="connect" onclick="connect();">Connect</button>
<button id="disconnect" disabled="disabled" onclick="disconnect();">Disconnect</button>
</div>
<div id="conversationDiv">
<labal>名字</labal><input type="text" id="name" />
<button id="sendName" onclick="sendName();">Send</button>
<p id="response"></p>
</div>
</div> </body>
</html>
<html>
<head>
<meta charset="UTF-8">
<title>Hello queue</title>
<script src="sock.js"></script>
<script src="stomp.js"></script>
<script src="jquery-3.2.1.min.js"></script>
<script type="text/javascript">
var stompClient = null;
function setConnected(connected){
document.getElementById("connect").disabled = connected;
document.getElementById("disconnect").disabled = !connected;
$("#response").html();
}
function connect() {
var socket = new SockJS("/queueServer");
stompClient = Stomp.over(socket);
stompClient.connect({}, function(frame) {
setConnected(true);
console.log('Connected: ' + frame);
stompClient.subscribe('/user/'+document.getElementById('user').value+'/message', function(response){
var response1 = document.getElementById('response');
var p = document.createElement('p');
p.style.wordWrap = 'break-word';
p.appendChild(document.createTextNode(response.body));
response1.appendChild(p);
});
});
} function disconnect() {
if (stompClient != null) {
stompClient.disconnect();
}
setConnected(false);
console.log("Disconnected");
} function sendName() {
var name = document.getElementById('name').value;
console.info(1111111111);
stompClient.send("/queue", {}, JSON.stringify({ 'name': name}));
}
</script>
</head>
<body onload="disconnect()">
<noscript><h2 style="color: #ff0000">Seems your browser doesn't support Javascript! Websocket relies on Javascript being enabled. Please enable
Javascript and reload this page!</h2></noscript>
<div>
<div>
<labal>用户</labal><input type="text" id="user" />
<button id="connect" onclick="connect();">Connect</button>
<button id="disconnect" disabled="disabled" onclick="disconnect();">Disconnect</button>
</div>
<div id="conversationDiv">
<labal>名字</labal><input type="text" id="name" />
<button id="sendName" onclick="sendName();">Send</button>
<p id="response"></p>
</div>
</div> </body>
</html>

  启动项目后,先访问topic.html,如图所示

  访问queue.html,首先以不同的用户名建立连接,如图所示

  

  zhangsan窗口发送12345后:

  lisi窗口发送67890后:

  由此便实现了服务端两种推送消息的方式(广播 和点对点)。

转自http://www.cnblogs.com/hhhshct/p/8849449.html  君临-行者无界

 
 

websocket socketJs的更多相关文章

  1. spring websocket 和socketjs实现单聊群聊,广播的消息推送详解

    spring websocket 和socketjs实现单聊群聊,广播的消息推送详解 WebSocket简单介绍 随着互联网的发展,传统的HTTP协议已经很难满足Web应用日益复杂的需求了.近年来,随 ...

  2. tomcat 7下spring 4.x mvc集成websocket以及sockjs完全参考指南

    之所以sockjs会存在,说得不好听点,就是因为微软是个流氓,现在使用windows 7的系统仍然有近半,而windows 7默认自带的是ie 8,有些会自动更新到ie 9,但是大部分非IT用户其实都 ...

  3. 学习WebSocket(一):Spring WebSocket的简单使用

    1.什么是websocket? WebSocket协议定义了一种web应用的新功能,它实现了服务器端和客户端的全双工通信.全双工通信即通信的双方可以同时发送和接收信息 的信息交互方式.它是继Java ...

  4. WebSocket 服务器4

    Java Websocket实例 Websocket   2015-04-11 14:11:54 发布 您的评价:       4.4   收藏     6收藏 介绍 现很多网站为了实现即时通讯,所用 ...

  5. Java中Websocket使用实例解读

    介绍 现在很多网站为了实现即时通讯,所用的技术都是轮询(polling).轮询是在特定的的时间间隔(如每1秒),由浏览器对服务器发出HTTP request,然后由服务器返回最新的数据给客服端的浏览器 ...

  6. java 实现websocket的两种方式

    简单说明 1.两种方式,一种使用tomcat的websocket实现,一种使用spring的websocket 2.tomcat的方式需要tomcat 7.x,JEE7的支持. 3.spring与we ...

  7. 补习系列(20)-大话 WebSocket 与 "尬聊"的实现

    目录 一.聊聊 WebSocket 二.Stomp 是个什么鬼 三.SpringBoot 整合 WebSocket A. 引入依赖 B. WebSocket 配置 C. 控制器 D. 前端实现 四.参 ...

  8. spring boot websocket stomp 实现广播通信和一对一通信聊天

    一.前言 玩.net的时候,在asp.net下有一个叫 SignalR 的框架,可以在ASP .NET的Web项目中实现实时通信.刚接触java寻找相关替代品,发现 java 体系中有一套基于stom ...

  9. Socket,ServerSocket,WebSocket

    一 区别 首先来说下区别吧, Socket和ServerSocket 指传输层网络接口协议,是基于套接字的服务端和客户端实现. 而WebScoket是应用层协议,是客户端-服务器的异步通信方法,用于双 ...

随机推荐

  1. Java源码解析|HashMap的前世今生

    HashMap的前世今生 Java8在Java7的基础上,做了一些改进和优化. 底层数据结构和实现方法上,HashMap几乎重写了一套 所有的集合都新增了函数式的方法,比如说forEach,也新增了很 ...

  2. NoUniqueBeanDefinitionException常见异常!!

    Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of ...

  3. String的常见面试题

    下面代码,是我前些天在网上搜集的一小部分String的面试题.个人觉得感触很深,希望对大家有所帮助.不好的也请大家批评指正. package com.zys.string; public class ...

  4. Vue-cli中的跳转

    Vue-cli中的跳转 一.页面中跳转指定网页 写法一: <router-link :to="{name:'home'}"> 这里的name是在VUE路由里面的 写法二 ...

  5. 【前端词典】4 个实用有趣的 JS 特性

    前言 最近在学习的过程中发现了我之前未曾了解过的一些特性,发现有些很有趣并且在处理一些问题的时候可以给我一个新的思路. 这里我将这些特性介绍给大家. 4 个有趣的 JS 特性 利用 a 标签解析 UR ...

  6. Unix 线程改变创建进程中变量的值(2)

    执行环境:Linux ubuntu 4.4.0-31-generic #50-Ubuntu SMP Wed Jul 13 00:07:12 UTC 2016 x86_64 x86_64 x86_64 ...

  7. Redis事务深入解析和使用

    作为关系型数据库中一项非常重要的基础功能--事务,在 Redis 中是如何处理并使用的? 1.前言 事务指的是提供一种将多个命令打包,一次性按顺序地执行的机制,并且保证服务器只有在执行完事务中的所有命 ...

  8. 使用 Hexo,Material Theme 以及 Github Pages 搭建个人博客

    准备条件 Node.js npm Git GitHub账号 开始搭建 hexo init Blog cd Blog npm install hexo-deployer-git --save npm i ...

  9. 百万年薪python之路 -- HTML标签

    HTML标签 html标签分类 html标签又叫做html元素,它分为块级元素和内联元素(也可以叫做行内元素),都是html规范中的概念. 标题 h1 h2 h3 h4 h5 h6 列表 ol ul ...

  10. java类对象的初始化顺序

    在下面这个例子中,我们分别在父类和子类中测试了静态代码块.普通代码块.静态成员变量.普通成员变量.构造器.静态内部类. 一:代码块及变量测试 class Field{ public static St ...