WebSocket实现Java后台消息推送
1.什么是WebSocket
WebSocket协议是基于TCP的一种新的网络协议。它实现了浏览器与服务器全双工(full-duplex)通信——允许服务器主动发送信息给客户端。
2.实现原理
在实现websocket连线过程中,需要通过浏览器发出websocket连线请求,然后服务器发出回应,这个过程通常称为“握手” 。在 WebSocket API,浏览器和服务器只需要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道。两者之间就直接可以数据互相传送。
3.优点
在以前的消息推送机制中,用的都是 Ajax 轮询(polling),在特定的时间间隔由浏览器自动发出请求,将服务器的消息主动的拉回来,这种方式是非常消耗资源的,因为它本质还是http请求,而且显得非常笨拙。而WebSocket 在浏览器和服务器完成一个握手的动作,在建立连接之后,服务器可以主动传送数据给客户端,客户端也可以随时向服务器发送数据。
4.WebSocket和Socket的区别
1.WebSocket:
websocket通讯的建立阶段是依赖于http协议的。最初的握手阶段是http协议,握手完成后就切换到websocket协议,并完全与http协议脱离了。
建立通讯时,也是由客户端主动发起连接请求,服务端被动监听。
通讯一旦建立连接后,通讯就是“全双工”模式了。也就是说服务端和客户端都能在任何时间自由得发送数据,非常适合服务端要主动推送实时数据的业务场景。
交互模式不再是“请求-应答”模式,完全由开发者自行设计通讯协议。
通信的数据是基于“帧(frame)”的,可以传输文本数据,也可以直接传输二进制数据,效率高。当然,开发者也就要考虑封包、拆包、编号等技术细节。
2.Socket:
服务端监听通讯,被动提供服务;客户端主动向服务端发起连接请求,建立起通讯。
每一次交互都是:客户端主动发起请求(request),服务端被动应答(response)。
服务端不能主动向客户端推送数据。
通信的数据是基于文本格式的。二进制数据(比如图片等)要利用base64等手段转换为文本后才能传输。
5.WebSocket客户端:
var websocket = null;
var host = document.location.host;
var username = "${loginUsername}"; // 获得当前登录人员的userName
// alert(username)
//判断当前浏览器是否支持WebSocket
if ('WebSocket' in window) {
alert("浏览器支持Websocket")
websocket = new WebSocket('ws://'+host+'/mm-dorado/webSocket/'+username);
} else {
alert('当前浏览器 Not support websocket')
} //连接发生错误的回调方法
websocket.onerror = function() {
alert("WebSocket连接发生错误")
setMessageInnerHTML("WebSocket连接发生错误");
}; //连接成功建立的回调方法
websocket.onopen = function() {
alert("WebSocket连接成功")
setMessageInnerHTML("WebSocket连接成功");
} //接收到消息的回调方法
websocket.onmessage = function(event) {
alert("接收到消息的回调方法")
alert("这是后台推送的消息:"+event.data);
websocket.close();
alert("webSocket已关闭!")
} //连接关闭的回调方法
websocket.onclose = function() {
setMessageInnerHTML("WebSocket连接关闭");
} //监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
window.onbeforeunload = function() {
closeWebSocket();
} //关闭WebSocket连接
function closeWebSocket() {
websocket.close();
} //将消息显示在网页上
function setMessageInnerHTML(innerHTML) {
document.getElementById('message').innerHTML += innerHTML + '<br/>';
}
6.WebSocket服务端(java后台):
1.核心类:
package com.mes.util; import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; 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.springframework.stereotype.Component;
import org.springframework.stereotype.Service; import com.google.gson.JsonObject; import net.sf.json.JSONObject;
@ServerEndpoint("/webSocket/{username}")
public class WebSocket {
private static int onlineCount = 0;
private static Map<String, WebSocket> clients = new ConcurrentHashMap<String, WebSocket>();
private Session session;
private String username; @OnOpen
public void onOpen(@PathParam("username") String username, Session session) throws IOException { this.username = username;
this.session = session; addOnlineCount();
clients.put(username, this);
System.out.println("已连接");
} @OnClose
public void onClose() throws IOException {
clients.remove(username);
subOnlineCount();
} @OnMessage
public void onMessage(String message) throws IOException { JSONObject jsonTo = JSONObject.fromObject(message);
String mes = (String) jsonTo.get("message"); if (!jsonTo.get("To").equals("All")){
sendMessageTo(mes, jsonTo.get("To").toString());
}else{
sendMessageAll("给所有人");
}
} @OnError
public void onError(Session session, Throwable error) {
error.printStackTrace();
} public void sendMessageTo(String message, String To) throws IOException {
// session.getBasicRemote().sendText(message);
//session.getAsyncRemote().sendText(message);
for (WebSocket item : clients.values()) {
if (item.username.equals(To) )
item.session.getAsyncRemote().sendText(message);
}
} public void sendMessageAll(String message) throws IOException {
for (WebSocket item : clients.values()) {
item.session.getAsyncRemote().sendText(message);
}
} public static synchronized int getOnlineCount() {
return onlineCount;
} public static synchronized void addOnlineCount() {
WebSocket.onlineCount++;
} public static synchronized void subOnlineCount() {
WebSocket.onlineCount--;
} public static synchronized Map<String, WebSocket> getClients() {
return clients;
}
}
2.在自己代码中的调用:
WebSocket ws = new WebSocket();
JSONObject jo = new JSONObject();
jo.put("message", "这是后台返回的消息!");
jo.put("To",invIO.getIoEmployeeUid());
ws.onMessage(jo.toString());
7.所需maven依赖:
<!-- webSocket 开始-->
<dependency>
<groupId>javax.websocket</groupId>
<artifactId>javax.websocket-api</artifactId>
<version>1.1</version>
<scope>provided</scope>
</dependency> <dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>7.0</version>
<scope>provided</scope>
</dependency>
<!-- webSocket 结束-->
WebSocket实现Java后台消息推送的更多相关文章
- Websocket实现Java后台主动推送消息到前台
写在前面 需求: 项目测试, 缺少用户登录失败给admin推送消息, 想到这个方式, 当用户登录失败时, admin用户会在页面看到咣咣乱弹的alert. 正文 pom.xml <!-- web ...
- 结合实际需求,在webapi内利用WebSocket建立单向的消息推送平台,让A页面和服务端建立WebSocket连接,让其他页面可以及时给A页面推送消息
1.需求示意图 2.需求描述 原本是为了给做unity3d客户端开发的同事提供不定时的消息推送,比如商城购买道具后服务端将道具信息推送给客户端. 本篇文章简化理解,用“相关部门开展活动,向全市人民征集 ...
- xmpp关于后台挂起的消息接收,后台消息推送,本地发送通知
想问下,在xmpp即时通讯的项目中,我程序如果挂起了,后台有消息过来,我这边的推送不过来,所以我的通知就会收不到消息,当我重新唤醒应用的时候,他才会接收到通知,消息就会推送过来,我在plist哪里设置 ...
- 【转】java即时消息推送
整个例子的源码下载:http://pan.baidu.com/s/1gfFYSbp 下载服务端jar文件 Comet4J目前仅支持Tomcat6.7版本,根据您所使用的Tomcat版本下载[comet ...
- Android后台消息推送-android学习之旅(71)
建议使用第三方的sdk,比如极光推送,小米推送,百度推送
- spring boot下WebSocket消息推送(转)
原文地址:https://www.cnblogs.com/betterboyz/p/8669879.html WebSocket协议 WebSocket是一种在单个TCP连接上进行全双工通讯的协议.W ...
- spring boot下WebSocket消息推送
WebSocket协议 WebSocket是一种在单个TCP连接上进行全双工通讯的协议.WebSocket通信协议于2011年被IETF定为标准RFC 6455,并由RFC7936补充规范.WebSo ...
- Android P正式版即将到来:后台应用保活、消息推送的真正噩梦
1.前言 对于广大Android开发者来说,Android O(即Android 8.0)还没玩热,Andriod P(即Andriod 9.0)又要来了. 下图上谷歌官方公布的Android P ...
- 基于APNs最新HTTP/2接口实现iOS的高性能消息推送(服务端篇)
1.前言 本文要分享的消息推送指的是当iOS端APP被关闭或者处于后台时,还能收到消息/信息/指令的能力. 这种在APP处于后台或关闭情况下的消息推送能力,通常在以下场景下非常有用: 1)IM即时通讯 ...
随机推荐
- Eclipse中Junit测试中@Before不执行
场景 在使用Junit进行单元测试时,一部分获取JPA的entityManager的代码将其放在了 @Before标注的方法中,这样每次执行@TEST标注的方法时会首先执行@Before标注的方法. ...
- Cobalt Strike系列教程第四章:文件/进程管理与键盘记录
Cobalt Strike系列教程分享如约而至,新关注的小伙伴可以先回顾一下前面的内容: Cobalt Strike系列教程第一章:简介与安装 Cobalt Strike系列教程第二章:Beacon详 ...
- Linux Shell之监测程序
监测程序 一.探查进程 当程序运行在系统上时,我们称之为进程(process).想要监测这些进程,需要熟悉ps命令的用法.ps命令好比工具中的瑞士军刀,它能输出运行在系统上的所有程序的许多信息. 但是 ...
- WebMagic使用代理ip爬数据解决HTTP407问题
手头一个小活儿是爬竞品网站数据.使用webmagic来实现.光公司ip不行,被封了就会影响业务正常访问.刚好公司另一个项目购买了代理IP资源“站大爷”,那个项目夭折了,于是申请借来用用. 调通站大爷提 ...
- Saltstack_使用指南12_配置管理-jinja模板
1. 说明 下文的案例是根据上一篇文章进行的修改.因此请优先读取上一章博文内容<Saltstack_使用指南11_配置管理-状态之间依赖关系> 2. 主机规划 salt 版本 [root@ ...
- 以特定用户和组来执行某个程序 - linux
运行cockpit 服务时,我们指定运行此程序的用户和组:cockpit-ws cockpit-ws 我们使用 sudo -u -g 命令来进行运行: sudo -u cockpit-ws -g co ...
- Linxu:在Linux下访问Windows的共享目录
在 Windows xp 上设置一个共享目录 共享目录:d:\myfiles 在 Linux 下安装 samba-client 客户端 yum install samba-client 安装 cifs ...
- linux系统编程(一)概述
glibc库封装了linux系统调用,并提供c语言接口 所以学习linux系统编程,主要参考glibc库系统调用相关api 一.进程控制: fork 创建一个新进程 clone 按指定条件创建子进程 ...
- Java总结转载,持续更新。。。
1.Java中内存划分 https://www.cnblogs.com/yanglongbo/p/10981680.html
- win7+vim搭建+verilog HDL IDE
参考地址:http://www.huangdc.com/421 参考文章为2016年,部分更新贴于文章内了 安装下载vim vim在win下叫gvim,下载地址:https://www.vim.org ...