ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

体验了一把websocket

2022-01-18 20:59:29  阅读:145  来源: 互联网

标签:websocket socket 一把 void WebSocket 体验 import public


WebSocket是个啥

态度明确点,这玩意儿是个协议。
从http1.1相较于http1.0增加的功能之一就是长连接(Persistent Connection),作用就是为了弥补http无法长时间保持活性的缺点,让以前只能通过轮询实现的功能看起来优雅一点。好嘛,原理上支持了之后,我这http里没有对应的协议咋办。WebSocket就来了。

WebSocket有啥特点

直接上图
websocket请求内容
相较于http请求多了几个东西:

Upgrade: websocket
Connection: Upgrade

请求用这俩告诉服务器,老子是websocket请求,你注意点,别给我割断喽。

Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
Sec-WebSocket-Key: pHl+HeJx5QV8NZuTw0xtYQ==
Sec-WebSocket-Version: 13

服务器:出示一下你的key以及您需要的服务类型Extensions,哦哦您是一三版的,欢迎欢迎~

Sec-WebSocket-Accept: iKC4KsGSKf4cna4SdMVX0rmjQik=
Sec-WebSocket-Extensions: permessage-deflate;client_max_window_bits=15
Upgrade: websocket

服务器:这是您今晚的身份卡请收好,这边请。

WebSocket的作用

websocket常用于实现数据更新的实时通知的业务场景。区别于ajax轮询,websocket只需要一次握手便能与服务器建立链接,而且信息由服务器端推送通知。

WebSocket代码实现

前端(vue组件):

<script>
const df = function (ms) {return function (e) {console.log(`webSocket---${ms}---webSocket---${e.data || ""}`)}}
export default {
  name:"webConnection",
  props:{
    url:{
      default:"",
      type:String
    },
    onopen:{
      default:df('开始链接'),
      type:Function
    },
    onmessage:{
      default:df('收到消息'),
      type:Function
    },
    onclose:{
      default:df('关闭'),
      type:Function
    },
    one rror:{
      default:df('发生错误'),
      type:Function
    }
  },
  data() {
    return {
      socket:null
    }
  },
  computed:{
    WebSocketUrl:function() {
      let url = "";
      this.url.includes('https') ? 
      url = this.url.replace(new RegExp(/https/),'wss') : 
      url = this.url.replace(new RegExp(/http/),'ws') ;
      return url;
    }
  },
  methods:{
    Connect() {
      if(typeof(WebSocket) === "undefined") return;
      try {
        this.socket = new WebSocket(this.WebSocketUrl);
        this.socket.onopen = this.onopen;
        this.socket.onmessage = this.onmessage;
        this.socket.onclose = this.onclose;
        this.socket.onerror = this.onerror;
        console.log('连接成功');
      } catch(err) {
        console.log('连接失败');
      }
    },
    sendMsg(msg) {
      if(this.socket && this.socket.readyState === 1) {
        this.socket.send(msg);
      } else {
        alert('暂无链接存在,请先建立连接')
      }
    },
    reConnect() {
      if(this.socket && this.socket.readyState === 1) {
        this.disConnect();
      }
      this.Connect();
    },
    destoryConnect() {
      this.disConnect();
      this.socket = null;
    },
    disConnect() {
      if(this.socket && this.socket.readyState !== 3) {
        this.socket.close();
      }
    }
  },
  mounted() {
    this.Connect();
  },
  render() {},
  beforeDestroy() {
    this.destoryConnect();
  }
}
</script>

后端:

配置类

public class WebSocketConfig {
        @Bean
        public ServerEndpointExporter serverEndpointExporter() {
            return new ServerEndpointExporter();
        }
    }

链接层

import java.io.IOException;
import java.util.concurrent.CopyOnWriteArraySet;

import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;



import org.springframework.stereotype.Component;

//@ServerEndpoint("/websocket/{user}")
@ServerEndpoint(value = "/websocket")
@Component
public class WebSocketServer {
    //静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
    private static int onlineCount = 0;
    //concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。
    private static CopyOnWriteArraySet<WebSocketServer> webSocketSet = new CopyOnWriteArraySet<WebSocketServer>();

    //与某个客户端的连接会话,需要通过它来给客户端发送数据
    private Session session;

    /**
     * 连接建立成功调用的方法*/
    @OnOpen
    public void onOpen(Session session) {
        this.session = session;
        webSocketSet.add(this); //加入set中
        addOnlineCount(); //在线数加1

        try {
            sendMessage("连接成功");
        } catch (IOException e) {

        }
    }

    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose() {
        webSocketSet.remove(this); //从set中删除
        subOnlineCount(); //在线数减1

    }

    /**
     * 收到客户端消息后调用的方法
     *
     * @param message 客户端发送过来的消息*/
    @OnMessage
    public void onMessage(String message, Session session) {
        for (WebSocketServer item : webSocketSet) {
            try {
                item.sendMessage(message);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     *
     * @param session
     * @param error
     */
    @OnError
    public void one rror(Session session, Throwable error) {

        error.printStackTrace();
    }


    public void sendMessage(String message) throws IOException {
        this.session.getBasicRemote().sendText(message);
    }


    /**
     * 群发自定义消息
     * */
    public static void sendInfo(String message) throws IOException {

        for (WebSocketServer item : webSocketSet) {
            try {
                item.sendMessage(message);
            } catch (IOException e) {
                continue;
            }
        }
    }

    public static synchronized int getOnlineCount() {
        return onlineCount;
    }

    public static synchronized void addOnlineCount() {
        WebSocketServer.onlineCount++;
    }

    public static synchronized void subOnlineCount() {
        WebSocketServer.onlineCount--;
    }
}

接口层

import java.io.IOException;
import javax.servlet.http.HttpServletRequest;

import com.xzs1.first.service.WebSocketServer;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping(value="/websocket")
public class webscoket {

    @RequestMapping(value="/sendToOne", produces = {"application/json; charset=utf-8"},method=RequestMethod.POST)
    public void sendToOne(HttpServletRequest request,String message){
        String str = message;
        try {
            WebSocketServer.sendInfo(str);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

实现效果

(手动藏起报错)
在这里插入图片描述

标签:websocket,socket,一把,void,WebSocket,体验,import,public
来源: https://blog.csdn.net/qq_43477426/article/details/122567814

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有