spring websocket之sockjs超简单现实

        最近做个东西,要用到服务器主动推送的功能,于是查了相关的资料,现就对查到的东西做下总结。

大致有如下几种实现策略:

1,轮训 ajax:缺陷:由浏览器发起,不实时,大多数时候服务器端并没有数据,还得建立一次连接处理,白浪费表情。舍弃。

2,HTML5 SEE:缺陷:代码写完后才发现的,内部实际上还是 1 的实现策略,无语删掉代码。舍弃。

3,Comet :缺陷:本人较笨,看了半天没理解它是要干嘛,感觉代码很复杂,服务器端又是BEGIN,又是END,又是READ的,前端代码也复杂,看几下就觉得头昏脑胀。放弃治疗。

4,websocket:似乎有几种实现方式,有纯servlet的。也有依赖spring的,作为懒惰份子,自然是选择拿来就用的spring方式。spring里面呢,又分为实现纯servlet方式的和sockjs方式的。能出现编外东西的肯定还是纯的用起来太麻烦嘛,不用想,直接使用 spring sockjs 方式的实现。OK,就是它了。

 

        以下为最简略实现方式,连接的开关之类的,咱根本不关心,只要能拿来通信传数据就OK,基于此,快速实现如下:

 

1,得先去  www.sockjs.org  下载一个 js 文件,名字叫:sockjs.min.js

    这个 js 文件,用于 web 客户端这边。整个代码如下:

<script src="sockjs.min.js"></script>
<script type="text/javascript">
var sock = new SockJS('${path}/pushEPC');
sock.onmessage = function(e) {
	alert(e.data);
};
</script>

 

2,后台新建一个java类,大概代码如下:

import java.util.LinkedList;

import javax.annotation.PostConstruct;

import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

public class PushEPCHandler extends TextWebSocketHandler {
	private static WebSocketSession session;

	@Override
	public void afterConnectionEstablished(WebSocketSession session) throws Exception {
		this.session = session;
	}

	@PostConstruct
	public void startReader1() {
		final LinkedList<String> linkedList = new LinkedList<>();
		linkedList.add("2017-W12-001");
		linkedList.add("QQQQ-13097");
		linkedList.add("QQQQ-13098");
		linkedList.add("QQQQ-13099");
		linkedList.add("QQQQ-131");
		linkedList.add("QQQQ-1310");
		linkedList.add("QQQQ-13100");
		linkedList.add("QQQQ-13101");
		linkedList.add("QQQQ-13102");
		linkedList.add("QQQQ-13103");
		linkedList.add("QQQQ-13104");
		linkedList.add("QQQQ-13105");
		new Thread(() -> {
			try {

				while (true) {
					Thread.sleep(3000);
					try {
						if (session != null && linkedList.size() > 0) {
							session.sendMessage(new TextMessage(linkedList.poll() + ""));
						}
					} catch (Exception e) {
					}
				}
			} catch (Exception e) {
			}
		}).start();
	}
}
  • 这个演示类有如下问题:

        a,单 WebSocketSession 了,难道一个服务器只供给一个用户使用?作为 web 服务器显然是多用户的,那么第一步的前台 js 中 new SockJS 的时候,一起是3个参数项的,另外2个参数项可以传递目前是哪个用户的标识,这样就可以在后台区分出来连接是哪个用户建立的,然后再改改如上代码,即可实现多用户通信。

        b, @PostConstruct 注解的方法,实际中是不许需要的,这边只是为了演示后台把数据推送到前台去了

  • 这个类编写的注意点:

        a,在连接建立起来之后,往前台推送数据,就是使用方法:

session.sendMessage(new TextMessage(linkedList.poll() + ""));

        b,继承实现的 afterConnectionEstablished  方法,一定要快速失败(?这个词可能用的不准确)。啥意思呢?

        就是这个方法,必须秒秒钟就执行完毕。切忌不要在这个方法中写耗时较长的操作,因为一旦写了,前台建立连接没有很快速的建立起来时,前台的 js 工具就会尝试其它协议或者底层方式建立连接,具体都尝试了哪些方式,我也懒得去搞清楚,总之,反而更容易连接失败导致通信不了。

        那么,就更不能写一个 while(true) 循环在这个方法里面,以达到其它模块有了信息持续往前台推送的目的啦。我们能推送,肯定是要持续推送的,这个目的没错儿,但不能在这个 afterConnectionEstablished  方法里面去实现,得像我样例代码这样,把 WebSocketSession  先拿到内存里持有住就行了,然后在另外的方法里通过它往前台推送信息。

        总而言之,你得让 afterConnectionEstablished  是死是活,快速给个话儿(结束掉)。

        c,继承 TextWebSocketHandler  类还有 另外2个比较常用的方法,一个是连接关闭时,一个是发送信息时。关闭时,在多用户环境下,当然的把我们持有的对象删除掉,不然内存泄漏了对吧?发送信息时可能要给加点料再处理一下统一格式之类的,这个看具体情况。

 

3,spring.xml 配置,大概代码如下:

头配置:

xmlns:websocket="http://www.springframework.org/schema/websocket

http://www.springframework.org/schema/websocket http://www.springframework.org/schema/websocket/spring-websocket.xsd

具体类配置:

<bean id="pushEPCHandler" class="com.xuanen.hardware.PushEPCHandler" />
<websocket:handlers>
	<websocket:mapping path="/pushEPC" handler="pushEPCHandler" />
	<websocket:sockjs />
</websocket:handlers>

        注意点,一定要写  <websocket:sockjs />  这个配置项,这个和前台的 sokejs 工具包是对应的,不写这个连接是建立不成功的。

 

4,可能的web.xml 配置如下:

给所有要通过的的 filter 和 servlet 加如下属性项:

<async-supported>true</async-supported>

这个主要用于建立通信较慢时,可能切换连接方式时,这个前台 js 工具会自动生成一大堆动态地址来调用。

 

5,需要的spring jar 包:

<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-websocket</artifactId>
	<version>5.0.3.RELEASE</version>
</dependency>
<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-messaging</artifactId>
	<version>5.0.3.RELEASE</version>
</dependency>

 

        怎么样,嘿简单吧?至于到处能查到的这种方式,还要写拦截器之类的,完全不在我考虑范围,哥们我用不到啊。一个简单的 websocket 通信样例,就是这么简单。

转载于:https://my.oschina.net/sxgkwei/blog/1617267

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值