内容简介:在
前言
web开发
也讲解了三章了,这章节开始讲解关于与前端通信相关知识。实现一个在线聊天室类似的功能或者后端推送消息到前端,在没有 WebSocket
时,读大学那伙还有接触过 DWR(Direct Web Remoting)
,也使用过轮询的方式,当 Servlet3.0
出来后,也有使用其异步连接机制进行前后端通信的。今天我们就来说说 WebSocket
。它是 HTML5
开始提供的。
关于WebSocket
WebSocket
是 HTML5
开始提供的一种在单个 TCP
连接上进行 全双工
通讯的协议。
在 WebSocket API
中,浏览器和服务器只需要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道。两者之间就直接可以数据互相传送。
浏览器通过 JavaScript
向服务器发出建立 WebSocket
连接的请求,连接建立以后,客户端和服务器端就可以通过 TCP
连接直接交换数据。
当获取 Web Socket
连接后,你可以通过 send() 方法来向服务器发送数据,并通过 onmessage 事件来接收服务器返回的数据。
对于前端,创建一个 WebSocket
对象,如下:
var Socket = new WebSocket(url, [protocol] );
说明:第一个参数 url, 指定连接的 URL。第二个参数 protocol 是可选的,指定了可接受的子协议。
WebSocker属性
以下是 WebSocket
对象的属性。假定我们使用了以上代码创建了 Socket
对象:
属性 | 描述 |
---|---|
Socket.readyState | 只读属性 readyState 表示连接状态,可以是以下值:<br>0 - 表示连接尚未建立。<br> 1 - 表示连接已建立,可以进行通信。<br>2 - 表示连接正在进行关闭。<br>3 - 表示连接已经关闭或者连接不能打开。 |
Socket.bufferedAmount | 只读属性 bufferedAmount 已被 send() 放入正在队列中等待传输,但是还没有发出的 UTF-8 文本字节数。 |
WebSocket事件
以下是 WebSocket 对象的相关事件。假定我们使用了以上代码创建了 Socket 对象:
事件 | 事件处理程序 | 描述 |
---|---|---|
open | Socket.onopen | 连接建立时触发 |
message | Socket.onmessage | 客户端接收服务端数据时触发 |
error | Socket.onerror | 通信发生错误时触发 |
close | Socket.onclose | 连接关闭时触发 |
WebSocket方法
以下是 WebSocket 对象的相关方法。假定我们使用了以上代码创建了 Socket 对象:
方法 | 描述 |
---|---|
Socket.send() | 使用连接发送数据 |
Socket.close() | 关闭连接 |
WebSocket实践
前面介绍了在 浏览器端
中 webSocket
的相关知识点,现在我们就来搭建一个后台对接应用,以实现一个简单的在线聊天室。
一点知识
后端关于 WebSocket
的实现是基于 JSR356
标准的。该标准的出现,统一了 WebSocket
的代码写法。只要支持web容器支持 JSR356
标准,那么实现方式是一致的。而目前实现方式有两种,一种是 注解
方式,另一种就是继承 继承javax.websocket.Endpoint
类了。
常用注解说明
-
@WebSocketEndpoint 注解是一个类层次的注解,它的功能主要是将目前的类定义成一个websocket服务器端。注解的值将被用于监听用户连接的终端访问URL地址。
-
@onOpen 打开一个新连接,即有新连接时,会调用被此注解的方法。
-
@onClose 关闭连接时调用。
-
@onMessage 当服务器接收到客户端发送的消息时所调用的方法。
-
@PathParam 接收
uri
参数的,与@PathVariable功能差不多,可通过url获取对应值
搭建一个简易聊天室
0.加入 POM
依赖。
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency>
1.编写控制层,对应 WebSocket
的各事件。同时抽取了个公用类,进行通用方法调用。
WebSocketController.java
/** * websocket 简易聊天 * @author oKong * */ //由于是websocket 所以原本是@RestController的http形式 //直接替换成@ServerEndpoint即可,作用是一样的 就是指定一个地址 //表示定义一个websocket的Server端 @Component @ServerEndpoint(value = "/my-chat/{usernick}") @Slf4j public class WebSocketController { /** * 连接事件 加入注解 * @param session */ @OnOpen public void onOpen(@PathParam(value = "usernick") String userNick,Session session) { String message = "有新游客[" + userNick + "]加入聊天室!"; log.info(message); WebSocketUtil.addSession(userNick, session); //此时可向所有的在线通知 某某某登录了聊天室 WebSocketUtil.sendMessageForAll(message); } @OnClose public void onClose(@PathParam(value = "usernick") String userNick,Session session) { String message = "游客[" + userNick + "]退出聊天室!"; log.info(message); WebSocketUtil.remoteSession(userNick); //此时可向所有的在线通知 某某某登录了聊天室 WebSocketUtil.sendMessageForAll(message); } @OnMessage public void OnMessage(@PathParam(value = "usernick") String userNick, String message) { //类似群发 String info = "游客[" + userNick + "]:" + message; log.info(info); WebSocketUtil.sendMessageForAll(message); } @OnError public void onError(Session session, Throwable throwable) { log.error("异常:", throwable); try { session.close(); } catch (IOException e) { e.printStackTrace(); } throwable.printStackTrace(); } }
WebSocketUtil.java
public class WebSocketUtil { /** * 简单使用map进行存储在线的session * */ private static final Map<String, Session> ONLINE_SESSION = new ConcurrentHashMap<>(); public static void addSession(String userNick,Session session) { //putIfAbsent 添加键—值对的时候,先判断该键值对是否已经存在 //不存在:新增,并返回null //存在:不覆盖,直接返回已存在的值 // ONLINE_SESSION.putIfAbsent(userNick, session); //简单示例 不考虑复杂情况。。怎么简单怎么来了。。 ONLINE_SESSION.put(userNick, session); } public static void remoteSession(String userNick) { ONLINE_SESSION.remove(userNick); } /** * 向某个用户发送消息 * @param session 某一用户的session对象 * @param message */ public static void sendMessage(Session session, String message) { if(session == null) { return; } // getAsyncRemote()和getBasicRemote()异步与同步 Async async = session.getAsyncRemote(); //发送消息 async.sendText(message); } /** * 向所有在线人发送消息 * @param message */ public static void sendMessageForAll(String message) { //jdk8 新方法 ONLINE_SESSION.forEach((sessionId, session) -> sendMessage(session, message)); } }
注意点:
- @ServerEndpoint的value值填写时, 开头需要加上
/
,不然会提示路径无效。 - 需要加上类型
@Component
注解,使得能被扫描到。 - 这里的
session
等,都在包**javax.websocket
**包下的,注意区分。
2.编写主启动类,主要是加入注解 @EnableWebSocket
和申明一个 Websocket endpoint
类。
@SpringBootApplication @EnableWebSocket @Slf4j public class Chapter19Application { public static void main(String[] args) { SpringApplication.run(Chapter19Application.class, args); log.info("Chapter19启动!"); } /** * 会自动注册使用了@ServerEndpoint注解声明的Websocket endpoint * 要注意,如果使用独立的servlet容器, * 而不是直接使用springboot的内置容器, * 就不要注入ServerEndpointExporter,因为它将由容器自己提供和管理。 */ @Bean public ServerEndpointExporter serverEndpointExporter() { return new ServerEndpointExporter(); } }
3.启动应用,利用在线的测试 工具 进行测试。这里直接使用了 http://coolaf.com/tool/chattest 进行测试。当然也可以自己写一个 html
了。
首先,输入我们的服务地址: ws://127.0.0.1:8080/my-chat/okong ,连接后就可以看见服务器返回的消息了。
我们再开一个标签页,然后继续以另一个身份进入:
这时,可以看见第一个页面开的,也收到消息了。现在我们发送一条消息:
然后,其中一个断开连接:
然后可以愉快聊天了,简单的一个聊天室就完成了。
参考资料
- https://docs.spring.io/spring/docs/4.3.18.RELEASE/spring-framework-reference/htmlsingle/#websocket
- https://docs.spring.io/spring-boot/docs/1.5.15.RELEASE/reference/htmlsingle/#boot-features-websockets
- http://www.oracle.com/technetwork/articles/java/jsr356-1937161.html
- http://www.runoob.com/html/html5-websocket.html
总结
本章节主要是讲解了 WebSocket
的使用。因为有统一标准的存在,编写 webSocket
也是很简单的。对于如何一对一聊天,大家可以自行编写下,因为知道了对方名称,就能找出对方的 session
然后就能发送消息了。
最后
目前互联网上很多大佬都有 SpringBoot
系列教程,如有雷同,请多多包涵了。本文是作者在电脑前一字一句敲的,每一步都是自己实践的。若文中有所错误之处,还望提出,谢谢。
老生常谈
499452441 lqdevOps
个人博客: http://blog.lqdev.cn
完整示例: https://github.com/xie19900123/spring-boot-learning/tree/master/chapter-19
原文地址: http://blog.lqdev.cn/2018/08/14/springboot/chapter-nineteen/
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Numerical Methods and Methods of Approximation in Science and En
Karan Surana / CRC Press / 2018-10-31
ABOUT THIS BOOK Numerical Methods and Methods of Approximation in Science and Engineering prepares students and other readers for advanced studies involving applied numerical and computational anal......一起来看看 《Numerical Methods and Methods of Approximation in Science and En》 这本书的介绍吧!