发布于2021-05-29 23:33 阅读(1069) 评论(0) 点赞(9) 收藏(1)
websocket 协议?
Websocket 协议是HTM5 协议,它的出现解决了客户端发起多个http 请求到服务器的资源浏览器必须经过长时间的轮询问题而产生的,websocket 实现了多路复用,全双工通信方式,该协议可以实现客户端和浏览器端同时发送数据。
websocket 与 http 协议的不同之处?
http 是超文本传输协议,是一个简单的请求-响应协议,通常运行在Tcp 之上。该协议是应用层协议,基于B/S 架构的通信协议。且该协议是一种无状态协议,即服务器不保留与客户端的交易的任何状态。HTTP 是一种面向连接的协议,允许传递任意类型的数据对象。
典型的HTTP 事物处理过程如下:
(1)客户端与服务器建立连接
(2)客户向服务器提出请求
(3)服务器接收请求,并根据请求返回相应的文件,作为应答。
(4)客户端与服务器关闭连接
下表中展示了websocket 协议与http协议的不同之处:
区别 | http | websocket |
---|---|---|
连接方式 | http1.0 即普通的http请求,一般是短连接,一次请求,三次握手,完毕之后立即断开 | websocket 是http 协议的升级,http1.1 默认是长连接方式,长连接代表:一次连接,在一定期限内保持连接,保持tcp不断开,双方都可以即时通讯,是一种全双工通讯协议 |
场景 | http协议更适合普通文件请求,不适合即时通讯,一般我们要得到及时信息,通过http方式,我们就需要不断轮询,网络资源消耗大 | websocket 更适合做即时通讯,不需要不断的轮询,一次连接,长时间有效。 |
代码实现
基于maven 构建项目工具实现:
pom.xml 导入依赖
在pom.xml 中导入 websocket 依赖,如下所示:
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-websocket </artifactId>
- </dependency>
编写websocketConfig 类
- @Configuration
- public class WebSocketConfig{
- /**
- * @return
- */
- @Bean
- public ServerEndpointExporter serverEndpointExporter() {
-
- return new ServerEndpointExporter();
- }
- }
实现WebSocket 协议类
- @ServerEndpoint("/websocket/{id}")
- @Component
- public class WebSockerServer{
-
- // session 会话集合
- private static ConcurrentHashMap<String, Session> map = new ConcurrentHashMap<String, Session>();
-
- // 当前会话
- private Session session;
- // id
- private String id = "";
-
- /**
- * 连接,打开会话
- *
- * @param session 服务器端与客户端建立连接,生成数据
- * @param id 客户端的唯一id
- */
- @OnOpen
- public void onOpen(Seesion session, @PathParam("id") String id){
-
- this.session = session;
- this.id = id;
- // 加入到map 集合中
- this.map.put(this.sid, this.session);
- }
-
- /**
- * 关闭当前会话
- */
- @OnClose
- public void onClose(){
- try{
- // 从名单中清除
- this.map.remvoe(this.sid);
- // 关闭会话
- this.session.close();
- } catch(IOException e){
- // TODO Auto-generated catch block
- e.printStackTrace()
- }
- }
-
- /**
- * 接受信息
- *
- * @param message 接收到信息
- */
- @OnMessage
- public void onMessage(String message){
- try{
- System.out.println("message:" + message);
-
- // 广播数据
- for(Entry<String, Session> entry: map.entrySet()){
- entry.getValue().getBasicRemote().sendText(message);
- }
- }catch(Exception e){
- e.printStackTrace();
- }
- }
-
- /**
- * 发送数据
- *
- * @param message 需要发送数据
- */
- public void sendMessage(String message){
- try{
- this.session.getBasicRemote().sendText(message);
- }catch(Exception e){
- e.printStackTrace();
- }
- }
- }
前端界面
- <!DOCTYPE html>
- <html lang="zh-CN">
- <head>
- <meta charset="utf-8">
- <meta http-equiv="X-UA-Compatible" content="IE=edge">
- <meta name="viewport" content="width=device-width, initial-scale=1">
- <!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
- <title>Bootstrap 101 Template</title>
- <link rel="stylesheet" type="text/css" href="../css/bootstrap.css" />
- <script src="../js/Vue2.6.11.js" type="text/javascript" charset="utf-8"></script>
- </head>
- <body>
- <div id="app">
- <div class="container">
- <form action="" method="">
- <div class="row">
- <div class="form-group col-md-6">
- <label>信息展示:</label>
- <textarea class="form-control" rows="10" cols="" v-model="showContent"></textarea>
- </div>
- <div class="col-md-6">
- <div class="row">
- <div class="form-group col-md-12">
- <label>发送人ID:</label>
- <input type="text" class="form-control" name="" v-model="id" />
- </div>
- </div>
- <div class="row">
- <div class="form-group col-md-12">
- <label>发送信息:</label>
- <textarea class="form-control" rows="6" cols="" v-model="sendContent"></textarea>
- </div>
- </div>
- <div class="row">
- <div class="form-group col-md-6">
- <button type="button" class="btn btn-primary btn-block" @click="sendMsg()">点击发送</button>
- </div>
- <div class="form-group col-md-6">
- <button type="button" class="btn btn-danger btn-block" @click="connect()">连接</button>
- </div>
- </div>
- </div>
- </div>
- </form>
- </div>
- </div>
-
- <script type="text/javascript">
- var vm = new Vue({
- el: '#app',
- data: {
- id: '',
- showContent: '',
- sendContent: '',
- socket: null
- },
- methods: {
- connect: function() {
- var lsocket;
- if (typeof(WebSocket) == "undefined") {
- console.log("您的浏览器不支持WebSocket,请更换浏览器");
- return;
- } else {
- console.log("您的浏览器支持WebSocket");
- if (this.id.trim() == "") {
- alert('连接之前必须指定唯一ID')
- return
- }
-
- lsocket = new WebSocket("ws://localhost:8080/websocket/" + this.id)
- this.socket = lsocket
-
- this.socket.onopen = function() {
- console.log('连接已开放')
- }
- this.socket.onerror = function() {
- alert('websocket出现error')
- }
- this.socket.onmessage = function(msg) {
- console.log(msg)
- vm.showContent += msg.data
- }
- }
- },
- sendMsg: function() {
- if(this.sendContent.trim()==""||this.socket==null)
- {
- alert('不能发送空的信息哦,发送信息前,要先连接')
- return
- }
- this.socket.send(this.sendContent)
- this.sendContent=''
- }
- },
- created: function() {
-
- }
- })
- </script>
- </body>
- </html>
启动类
- @SpringBootApplication
- public class AppWebSocket{
-
- public static void main(String[] args){
- SpringApplication.run(App.class, args);
- }
- }
作者:听说你没有见过我
链接:http://www.javaheidong.com/blog/article/207793/f50f4cf1a21571a6a5f7/
来源:java黑洞网
任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任
昵称:
评论内容:(最多支持255个字符)
---无人问津也好,技不如人也罢,你都要试着安静下来,去做自己该做的事,而不是让内心的烦躁、焦虑,坏掉你本来就不多的热情和定力
Copyright © 2018-2021 java黑洞网 All Rights Reserved 版权所有,并保留所有权利。京ICP备18063182号-2
投诉与举报,广告合作请联系vgs_info@163.com或QQ3083709327
免责声明:网站文章均由用户上传,仅供读者学习交流使用,禁止用做商业用途。若文章涉及色情,反动,侵权等违法信息,请向我们举报,一经核实我们会立即删除!