彩世界平台-彩世界时时app-彩世界开奖app苹果下载

热门关键词: 彩世界平台,彩世界时时app,彩世界开奖app苹果下载

您的位置:彩世界平台 > 新闻动态 > 彩世界平台WebSocket教程

彩世界平台WebSocket教程

发布时间:2019-10-20 16:20编辑:新闻动态浏览(125)

    WebSocket 教程

    2017/05/15 · 基础技术 · websocket

    原文出处: 阮一峰   

    WebSocket 是一种网络通信协议,很多高级功能都需要它。

    本文介绍 WebSocket 协议的使用方法。

    彩世界平台 1

    WebSocket

    提出正确的问题,往往等于解决了问题的大半。——海森堡

    彩世界平台 2

    Learn.png

    • ##### 百科定义

        WebSocket协议是基于TCP的一种新的网络协议。它实现了浏览器与服务器全双工(full-duplex)通信——允许服务器主动发送信息给客户端。WebSocket通信协议于2011年被IETF定为标准RFC 6455,并被RFC7936所补充规范。

    • ##### 同类技术

        Http协议。

    • ##### 对比同类的优缺点

      • 优点:

          对于http协议有长连接和短连接,短连接并且要实现三次握手,长连接要在一定时间内保持连接,并且http的head占用的字节比较大,传输速度慢,数据包大,如实时交互,服务器性能压力大,数据传输安全性差。而websocket传输数据为字节级,传输数据可自定义,数据量小对于手机应用讲:费用低),传输数据时间短,性能高,适合于客户端和服务器端之间信息实时交互,可以加密,数据安全性强。

      • 缺点:

          需对传输的数据进行解析,转化成应用级的数据;对开发人员的开发水平要求高;相对于Http协议传输,增加了开发量

    • ##### 组成部分

        客户端,服务端。

    • ##### 解决什么问题

        WebSocket支持推送服务,而http协议服务端永远是被动的,解决了http无法实现了服务端与客户端的实时交互。WebSocket的请求信息很短,而http协议的请求头head数据包很大,占用多余的带宽,降低服务端的性能压力。

        Http协议是无状态的协议,通俗的说就是,服务器因为每天要接待太多客户了,是个健忘鬼,你一挂电话,他就把你的东西全忘光了,把你的东西全丢掉了。你第二次还得再告诉服务器一遍。

      WebSocket 是什么原理?为什么可以实现持久连接?

    • ##### 没有这个技术前怎么做的

      • Polling(轮询)

          这种方式就是通过Browser/UA定时的向Web服务器发送http的Get请求,服务器收到请求后,就把最新的数据发回给客户端(Browser/UA),Browser/UA得到数据后,就将其显示出来,然后再定期的重复这一过程。虽然这样可以满足需求,但是也仍然存在一些问题,例如在某段时间内Web服务器端没有更新的数据,但是Browser/UA仍然需要定时的发送Get请求过来询问,那么Web服务器就把以前的老数据再传送过来,Browser/UA把这些没有变化的数据再显示出来,这样显然既浪费了网络带宽,又浪费了CPU的利用率。如果说把Browser发送Get请求的周期调大一些,就可以缓解这一问题,但是如果在Web服务器端的数据更新很快时,这样又不能保证Web应用程序获取数据的实时性。

      • Long Polling

          上面介绍了Polling遇到的问题,现在介绍一下LongPolling,它是对Polling的一种改进。
        Browser/UA发送Get请求到Web服务器,这时Web服务器可以做两件事情,第一,如果服务器端有新的数据需要传送,就立即把数据发回给Browser/UA,Browser/UA收到数据后,立即再发送Get请求给Web Server;第二,如果服务器端没有新的数据需要发送,这里与Polling方法不同的是,服务器不是立即发送回应给Browser/UA,而是把这个请求保持住,等待有新的数据到来时,再来响应这个请求;当然了,如果服务器的数据长期没有更新,一段时间后,这个Get请求就会超时,Browser/UA收到超时消息后,再立即发送一个新的Get请求给服务器。然后依次循环这个过程。
        这种方式虽然在某种程度上减小了网络带宽和CPU利用率等问题,但是仍然存在缺陷,例如假设服务器端的数据更新速率较快,服务器在传送一个数据包给Browser后必须等待Browser的下一个Get请求到来,才能传递第二个更新的数据包给Browser,那么这样的话,Browser显示实时数据最快的时间为2×RTT(往返时间),另外在网络拥塞的情况下,这个应该是不能让用户接受的。另外,由于http数据包的头部数据量往往很大(通常有400多个字节),但是真正被服务器需要的数据却很少(有时只有10个字节左右),这样的数据包在网络上周期性的传输,难免对网络带宽是一种浪费。

    • ##### 官方示例

        WebSocket-Web APIS
        WebSocket Client API

    • #### Demo

      • Js客户端代码

        var webSocket = new WebSocket('ws://localhost:8080/em/chat');
        
        webSocket.onerror = function(event) {
            onError(event)
        };
        
        webSocket.onopen = function(event) {
            onOpen(event)
        };
        //实时监听服务端反馈的信息
        webSocket.onmessage = function(event) {
            onMessage(event)
        };
        
        function onMessage(event) {
            document.getElementById('messages').innerHTML 
                += '<br />' + event.data;
        }
        
        function onOpen(event) {
            document.getElementById('messages').innerHTML 
                = 'Connection established';
            var text =document.getElementById('text').value;
            //想服务端传送数据
            webSocket.send(text);
        }
        
        function onError(event) {
            console.info(event.data);
        }
        
      • Java客户端代码

        @WebSocket(maxBinaryMessageSize = 60 * 1024)
        public class SimpleSocket
        {
            private final CountDownLatch closeLatch;
            @SuppressWarnings("unused")
            private Session session;
        
            private Map map = new HashMap<String,String>(16);
        
                public SimpleSocket()
                {
                    this.closeLatch = new CountDownLatch(1);
                }
    
                public boolean awaitClose(int duration, TimeUnit unit) throws InterruptedException
                {
                    return this.closeLatch.await(duration,unit);
                }
    
                @OnWebSocketClose
                public void onClose(int statusCode, String reason)
                {
                    System.out.printf("Connection closed: %d - %s%n",statusCode,reason);
                    this.session = null;
                    this.closeLatch.countDown(); // trigger latch
                }
    
                @OnWebSocketConnect
                public void onConnect(Session session)
                {
                    System.out.printf("Got connect: %s%n",session);
                    this.session = session;
                    try
                    {
                        Future<Void> fut;
    
                        //向服务端传送指令
                        map.put("ACTION","REMIND");
    
                        JSONObject dataJson=new JSONObject(map);
    
                        fut = session.getRemote().sendStringByFuture(dataJson.toString());
    
                        fut.get(2,TimeUnit.SECONDS); // wait for send to complete.
    
                        session.close(StatusCode.NORMAL,"I'm done");
                    }
                    catch (Throwable t)
                    {
                        t.printStackTrace();
                    }
                }
    
                @OnWebSocketMessage
                public void onMessage(String msg)
                {
                    //接受服务端接受的json字符串
                    JSONObject dataJson=new JSONObject(msg);
    
                    //判断指令
                    if ("REMIND".equals(dataJson.get("ACTION"))) {
    
                        //// TODO: 2017/11/20
                    }else{
    
                        //// TODO: 2017/11/20
                    }
    
                }
            }
    
        `注:java客户端代码使用环境适于Jdk8`
    
    -   服务端代码
    
            @ServerEndpoint("/api")
            public class WebSocketTestChat {
                Set<Session> session_list =null;
                @OnMessage
                public void onMessage(String message, Session session) 
                    throws IOException, InterruptedException {
    
                    JSONObject dataJson=new JSONObject(message);
    
                    String action = (String) dataJson.get("ACTION");
                    if(action.equals("REMIND")){
                        //// TODO: 2017/11/20
    
                    }else{
                        //// TODO: 2017/11/20
                    }
                    session_list =session.getOpenSessions();
                    for(Session s:session_list){
                        s.getBasicRemote().sendText(dataJson.toString());
                    }
                }
                @OnOpen
                public void onOpen () {
                }
    
                @OnClose
                public void onClose () {
                }
            }
    
    • ##### 分享

        https://github.com/zhangqiaobo/WebSockets_demo

    一、为什么需要 WebSocket?

    初次接触 WebSocket 的人,都会问同样的问题:我们已经有了 HTTP 协议,为什么还需要另一个协议?它能带来什么好处?

    答案很简单,因为 HTTP 协议有一个缺陷:通信只能由客户端发起。

    举例来说,我们想了解今天的天气,只能是客户端向服务器发出请求,服务器返回查询结果。HTTP 协议做不到服务器主动向客户端推送信息。

    彩世界平台 3

    这种单向请求的特点,注定了如果服务器有连续的状态变化,客户端要获知就非常麻烦。我们只能使用“轮询”:每隔一段时候,就发出一个询问,了解服务器有没有新的信息。最典型的场景就是聊天室。

    轮询的效率低,非常浪费资源(因为必须不停连接,或者 HTTP 连接始终打开)。因此,工程师们一直在思考,有没有更好的方法。WebSocket 就是这样发明的。

    二、简介

    WebSocket 协议在2008年诞生,2011年成为国际标准。所有浏览器都已经支持了。

    它的最大特点就是,服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话,属于服务器推送技术的一种。

    彩世界平台 4

    其他特点包括:

    (1)建立在 TCP 协议之上,服务器端的实现比较容易。

    (2)与 HTTP 协议有着良好的兼容性。默认端口也是80和443,并且握手阶段采用 HTTP 协议,因此不容易屏蔽,能通过各种 HTTP 代理服务器。

    (3)数据格式比较轻量,性能开销小,通信高效。

    (4)可以发送文本,也可以发送二进制数据。

    (5)没有同源限制,客户端可以与任意服务器通信。

    (6)协议标识符是ws(如果加密,则为wss),服务器网址就是 URL。

    ws://example.com:80/some/path

    1
    2
    ws://example.com:80/some/path
     

    彩世界平台 5

    三、客户端的简单示例

    WebSocket 的用法相当简单。

    下面是一个网页脚本的例子(点击这里看运行结果),基本上一眼就能明白。

    var ws = new WebSocket("wss://echo.websocket.org"); ws.onopen = function(evt) { console.log("Connection open ..."); ws.send("Hello WebSockets!"); }; ws.onmessage = function(evt) { console.log( "Received Message: " + evt.data); ws.close(); }; ws.onclose = function(evt) { console.log("Connection closed."); };

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    var ws = new WebSocket("wss://echo.websocket.org");
     
    ws.onopen = function(evt) {
      console.log("Connection open ...");
      ws.send("Hello WebSockets!");
    };
     
    ws.onmessage = function(evt) {
      console.log( "Received Message: " + evt.data);
      ws.close();
    };
     
    ws.onclose = function(evt) {
      console.log("Connection closed.");
    };      
     

    四、客户端的 API

    WebSocket 客户端的 API 如下。

    4.1 WebSocket 构造函数

    WebSocket 对象作为一个构造函数,用于新建 WebSocket 实例。

    var ws = new WebSocket('ws://localhost:8080');

    1
    2
    var ws = new WebSocket('ws://localhost:8080');
     

    执行上面语句之后,客户端就会与服务器进行连接。

    实例对象的所有属性和方法清单,参见这里。

    4.2 webSocket.readyState

    readyState属性返回实例对象的当前状态,共有四种。

    • CONNECTING:值为0,表示正在连接。
    • OPEN:值为1,表示连接成功,可以通信了。
    • CLOSING:值为2,表示连接正在关闭。
    • CLOSED:值为3,表示连接已经关闭,或者打开连接失败。

    下面是一个示例。

    switch (ws.readyState) { case WebSocket.CONNECTING: // do something break; case WebSocket.OPEN: // do something break; case WebSocket.CLOSING: // do something break; case WebSocket.CLOSED: // do something break; default: // this never happens break; }

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    switch (ws.readyState) {
      case WebSocket.CONNECTING:
        // do something
        break;
      case WebSocket.OPEN:
        // do something
        break;
      case WebSocket.CLOSING:
        // do something
        break;
      case WebSocket.CLOSED:
        // do something
        break;
      default:
        // this never happens
        break;
    }
     

    4.3 webSocket.onopen

    实例对象的onopen属性,用于指定连接成功后的回调函数。

    ws.onopen = function () { ws.send('Hello Server!'); }

    1
    2
    3
    4
    ws.onopen = function () {
      ws.send('Hello Server!');
    }
     

    如果要指定多个回调函数,可以使用addEventListener`方法。

    ws.addEventListener('open', function (event) { ws.send('Hello Server!'); });

    1
    2
    3
    4
    ws.addEventListener('open', function (event) {
      ws.send('Hello Server!');
    });
     

    本文由彩世界平台发布于新闻动态,转载请注明出处:彩世界平台WebSocket教程

    关键词:

上一篇:websocket探索其与语音、图片的能力

下一篇:没有了