精华内容
下载资源
问答
  • Websocket服务器推送技术的一种,最大的特点是服务器可以主动向客户端推送消息,客户端也可以主动向服务器发送消息。 WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。 WebSocket 使得...

    最近一直在做网关的项目,收获了不少关于网络协议的相关知识点,我打算把这些知识点都串起来完成一个大的项目,其中WebSocket就是其中的一个知识点

    WebSocket知识点

    Websocket 是服务器推送技术的一种,最大的特点是服务器可以主动向客户端推送消息,客户端也可以主动向服务器发送消息。
    WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。

    WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。

    在这里插入图片描述

    HTTP握手

    首先客户端向服务器发起HTTP请求,这一次的HTTP请求是客户端和服务端进行的协议升级,具体步骤如下:

    客户端发起请求:

    客户端会向服务端发送协议升级请求,客户端发送的HTTP报文示例如下:
    在这里插入图片描述
    其中比较重要的头部是:

    • Host请求头,其值为要请求的主机名。

    • Upgrade请求头,且其值必须为websocket,表示这个HTTP请求的目的是要申请升级到websocket协议,而不是其他协议。

    • Connection请求头,其值必须为Upgrade,表示这个HTTP请求是一个协议升级请求。

    • Sec-WebSocket-Key请求头,且其值为以BASE-64编码的随机字符串。服务器端会用这些数据来构造出一个SHA-1的信息摘要。把“Sec-WebSocket-Key”的值加上一个特殊字符串“258EAFA5-E914-47DA-95CA-C5AB0DC85B11”,然后计算SHA-1摘要,之后进行BASE-64编码,将结果做为“Sec-WebSocket-Accept”响应头的值,返回给客户端。如此操作,可以尽量避免普通HTTP报文被误认为WebSocket协议握手报文。

    • Sec-WebSocket-Version请求头,且其值必须为13,表示使用的WebSocket版本为13。

    服务器接收请求:

    服务端响应客户端的协议升级请求
    当服务端接收到客户端的协议升级请求时,如果服务端接受该协议升级请求,将会返回如下响应报文:

    HTTP/1.1 101 Switching Protocols
    Upgrade: websocket
    Connection: Upgrade
    Sec-WebSocket-Accept: fFBooB7FAkLlXgRSz0BT3v4hq5s=
    

    其中返回的101状态码的意思是同意将当前的HTTP协议切换到WebSocket协议。

    来自developer.mozilla.org:
    HTTP 101 Switching Protocol(协议切换)状态码表示服务器应客户端升级协议的请求(Upgrade请求头)正在进行协议切换。

    相比传统的AJAX轮询,Websockets能够大量地节省服务器的带宽,因为它只需要建立一次连接,从而不同传输大量相同的头部信息。

    golang实现websocket服务器

    下面我们使用golang实现websocket的服务器

    package main
    
    import (
    	"flag"
    	"html/template"
    	"log"
    	"net/http"
    	"github.com/gorilla/websocket"
    )
    
    var addr = flag.String("addr", "localhost:2003", "http service address")
    
    var upgrader = websocket.Upgrader{} // use default options
    
    func echo(w http.ResponseWriter, r *http.Request) {
    	c, err := upgrader.Upgrade(w, r, nil)
    	if err != nil {
    		log.Print("upgrade:", err)
    		return
    	}
    	defer c.Close()
    	for {
    		mt, message, err := c.ReadMessage()
    		if err != nil {
    			log.Println("read:", err)
    			break
    		}
    		log.Printf("recv: %s", message)
    		err = c.WriteMessage(mt, message)
    		if err != nil {
    			log.Println("write:", err)
    			break
    		}
    	}
    }
    
    func home(w http.ResponseWriter, r *http.Request) {
    	homeTemplate.Execute(w, "ws://"+r.Host+"/echo")
    }
    
    func main() {
    	flag.Parse()
    	log.SetFlags(0)
    	http.HandleFunc("/echo", echo)
    	http.HandleFunc("/", home)
    	log.Println("Starting websocket server at " + *addr)
    	log.Fatal(http.ListenAndServe(*addr, nil))
    }
    

    在以上的代码中我使用了github中的websocket类库,其中最核心的函数就是:upgrader.Upgrade(w, r, nil),它会返回一个connection,我们得到connnection之后就可以调用它的ReadMessage()和WriteMessage(mt, message)方法进行数据传输了

    下面我们深入解析一下Upgrade这个函数

    首先它会验证客户端传输过来的HTTP头部信息,如果头部信息不正确,就会返回对应的错误信息

    if !tokenListContainsValue(r.Header, "Connection", "upgrade") {
    		return u.returnError(w, r, http.StatusBadRequest, badHandshake+"'upgrade' token not found in 'Connection' header")
    	}
    
    	if !tokenListContainsValue(r.Header, "Upgrade", "websocket") {
    		return u.returnError(w, r, http.StatusBadRequest, badHandshake+"'websocket' token not found in 'Upgrade' header")
    	}
    
    	if r.Method != "GET" {
    		return u.returnError(w, r, http.StatusMethodNotAllowed, badHandshake+"request method is not GET")
    	}
    
    	if !tokenListContainsValue(r.Header, "Sec-Websocket-Version", "13") {
    		return u.returnError(w, r, http.StatusBadRequest, "websocket: unsupported version: 13 not found in 'Sec-Websocket-Version' header")
    	}
    
    	if _, ok := responseHeader["Sec-Websocket-Extensions"]; ok {
    		return u.returnError(w, r, http.StatusInternalServerError, "websocket: application specific 'Sec-WebSocket-Extensions' headers are unsupported")
    	}
    

    然后使用bufio创建writer和reader,并利用writer和reader创建connection

    var br *bufio.Reader
    	if u.ReadBufferSize == 0 && bufioReaderSize(netConn, brw.Reader) > 256 {
    		// Reuse hijacked buffered reader as connection reader.
    		br = brw.Reader
    	}
    
    	buf := bufioWriterBuffer(netConn, brw.Writer)
    
    	var writeBuf []byte
    	if u.WriteBufferPool == nil && u.WriteBufferSize == 0 && len(buf) >= maxFrameHeaderSize+256 {
    		// Reuse hijacked write buffer as connection buffer.
    		writeBuf = buf
    	}
    
    	c := newConn(netConn, true, u.ReadBufferSize, u.WriteBufferSize, u.WriteBufferPool, br, writeBuf)
    

    然后会设置返回的头部信息,比如101状态码、Upgrade、Connection并且会利用computeAcceptKey()这个函数计算Sec-WebSocket-Accept

    p = append(p, "HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: "...)
    	p = append(p, computeAcceptKey(challengeKey)...)
    	p = append(p, "\r\n"...)
    	if c.subprotocol != "" {
    		p = append(p, "Sec-WebSocket-Protocol: "...)
    		p = append(p, c.subprotocol...)
    		p = append(p, "\r\n"...)
    	}
    	if compress {
    		p = append(p, "Sec-WebSocket-Extensions: permessage-deflate; server_no_context_takeover; client_no_context_takeover\r\n"...)
    	}
    	for k, vs := range responseHeader {
    		if k == "Sec-Websocket-Protocol" {
    			continue
    		}
    		for _, v := range vs {
    			p = append(p, k...)
    			p = append(p, ": "...)
    			for i := 0; i < len(v); i++ {
    				b := v[i]
    				if b <= 31 {
    					// prevent response splitting.
    					b = ' '
    				}
    				p = append(p, b)
    			}
    			p = append(p, "\r\n"...)
    		}
    	}
    	p = append(p, "\r\n"...)
    

    下面我们开启WebSocket服务器,然后在浏览器输入对应的ip和端口,点击open按钮发起请求:
    在这里插入图片描述

    可以看到浏览器发送了一个带有Upgrade、Host、Sec-Websocket-Key等头部信息的HTTP请求,并接收到了带有Upgrade、Connection、
    Sec-WebSocket-Accept等头部的response信息

    在这里插入图片描述在这里插入图片描述

    再往后我们每次利用浏览器向服务器发送数据都能接收到服务器返回的信息,但是都没有产生对应的HTTP请求,可见我们已经成功实现了WebSocket传输的建立

    在这里插入图片描述

    展开全文
  • WebSocket(1)-- WebSocket API简介 WebSocket是html5新增加的一种通信协议,目前流行的浏览器都支持这个协议,例如Chrome,Safari,Firefox,Opera,IE等等,对该协议支持最早的应该是chrome,从ch

    【文章非原创,转载自:http://blog.csdn.net/yl02520/article/



    WebSocket(1)-- WebSocket API简介

    WebSocket是html5新增加的一种通信协议,目前流行的浏览器都支持这个协议,例如Chrome,Safari,Firefox,Opera,IE等等,对该协议支持最早的应该是chrome,从chrome12就已经开始支持,随着协议草案的不断变化,各个浏览器对协议的实现也在不停的更新。该协议还是草案,没有成为标准,不过成为标准应该只是时间问题了,从WebSocket草案的提出到现在已经有十几个版本了,目前最新的是版本17,所对应的协议版本号为13,目前对该协议支持最完善的浏览器应该是chrome,毕竟WebSocket协议草案也是Google发布的。

    1.     WebSocket API简介

    首先看一段简单的javascript代码,该代码调用了WebSockets的API。

    [javascript]  view plain copy 在CODE上查看代码片 派生到我的代码片
    1. var ws = new WebSocket(“ws://echo.websocket.org”);  
    2.   
    3. ws.onopen = function(){ws.send(“Test!”); };  
    4.   
    5. ws.onmessage = function(evt){console.log(evt.data);ws.close();};  
    6.   
    7. ws.onclose = function(evt){console.log(“WebSocketClosed!”);};  
    8.   
    9. ws.onerror = function(evt){console.log(“WebSocketError!”);};  

    这份代码总共只有5行,现在简单概述一下这5行代码的意义。

    第一行代码是在申请一个WebSocket对象,参数是需要连接的服务器端的地址,同http协议使用http://开头一样,WebSocket协议的URL使用ws://开头,另外安全的WebSocket协议使用wss://开头。

    第二行到第五行为WebSocket对象注册消息的处理函数,WebSocket对象一共支持四个消息 onopen, onmessage, onclose和onerror,当Browser和WebSocketServer连接成功后,会触发onopen消息;如果连接失败,发送、接收数据失败或者处理数据出现错误,browser会触发onerror消息;当Browser接收到WebSocketServer发送过来的数据时,就会触发onmessage消息,参数evt中包含server传输过来的数据;当Browser接收到WebSocketServer端发送的关闭连接请求时,就会触发onclose消息。我们可以看出所有的操作都是采用消息的方式触发的,这样就不会阻塞UI,使得UI有更快的响应时间,得到更好的用户体验。





    WebSocket(2)--为什么引入WebSocket协议

    Browser已经支持http协议,为什么还要开发一种新的WebSocket协议呢?我们知道http协议是一种单向的网络协议,在建立连接后,它只允许Browser/UA(UserAgent)向WebServer发出请求资源后,WebServer才能返回相应的数据。而WebServer不能主动的推送数据给Browser/UA,当初这么设计http协议也是有原因的,假设WebServer能主动的推送数据给Browser/UA,那Browser/UA就太容易受到攻击,一些广告商也会主动的把一些广告信息在不经意间强行的传输给客户端,这不能不说是一个灾难。那么单向的http协议给现在的网站或Web应用程序开发带来了哪些问题呢?

    让我们来看一个案例,现在假设我们想开发一个基于Web的应用程序去获取当前Web服务器的实时数据,例如股票的实时行情,火车票的剩余票数等等,这就需要Browser/UA与WebServer端之间反复的进行http通信,Browser不断的发送Get请求,去获取当前的实时数据。下面介绍几种常见的方式:

    1.     Polling


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

    2.     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个字节左右),这样的数据包在网络上周期性的传输,难免对网络带宽是一种浪费。

    通过上面的分析可知,要是在Browser能有一种新的网络协议,能支持客户端和服务器端的双向通信,而且协议的头部又不那么庞大就好了。WebSocket就是肩负这样一个使命登上舞台的。





    WebSocket(3)-- WebSocket协议简介

    WebSocket协议是一种双向通信协议,它建立在TCP之上,同http一样通过TCP来传输数据,但是它和http最大的不同有两点:1.WebSocket是一种双向通信协议,在建立连接后,WebSocket服务器和Browser/UA都能主动的向对方发送或接收数据,就像Socket一样,不同的是WebSocket是一种建立在Web基础上的一种简单模拟Socket的协议;2.WebSocket需要通过握手连接,类似于TCP它也需要客户端和服务器端进行握手连接,连接成功后才能相互通信。

    下面是一个简单的建立握手的时序图:

    这里简单说明一下WebSocket握手的过程。

    当Web应用程序调用new WebSocket(url)接口时,Browser就开始了与地址为url的WebServer建立握手连接的过程。

    1.     Browser与WebSocket服务器通过TCP三次握手建立连接,如果这个建立连接失败,那么后面的过程就不会执行,Web应用程序将收到错误消息通知。

    2.     在TCP建立连接成功后,Browser/UA通过http协议传送WebSocket支持的版本号,协议的字版本号,原始地址,主机地址等等一些列字段给服务器端。

    例如:

    [html]  view plain copy 在CODE上查看代码片 派生到我的代码片
    1. GET /chat HTTP/1.1  
    2. Host: server.example.com  
    3. Upgrade: websocket  
    4. Connection: Upgrade  
    5. Sec-WebSocket-Key:dGhlIHNhbXBsZSBub25jZQ==  
    6. Origin: http://example.com  
    7. Sec-WebSocket-Protocol: chat,superchat  
    8. Sec-WebSocket-Version: 13  

    3.     WebSocket服务器收到Browser/UA发送来的握手请求后,如果数据包数据和格式正确,客户端和服务器端的协议版本号匹配等等,就接受本次握手连接,并给出相应的数据回复,同样回复的数据包也是采用http协议传输。

    [html]  view plain copy 在CODE上查看代码片 派生到我的代码片
    1. HTTP/1.1 101 Switching Protocols  
    2. Upgrade: websocket  
    3. Connection: Upgrade  
    4. Sec-WebSocket-Accept:s3pPLMBiTxaQ9kYGzzhZRbK+xOo=  
    5. Sec-WebSocket-Protocol: chat  

    4.     Browser收到服务器回复的数据包后,如果数据包内容、格式都没有问题的话,就表示本次连接成功,触发onopen消息,此时Web开发者就可以在此时通过send接口想服务器发送数据。否则,握手连接失败,Web应用程序会收到onerror消息,并且能知道连接失败的原因。





    WebSocket(4)-- WebSocket与TCP、Http的关系

    WebSocket与http协议一样都是基于TCP的,所以他们都是可靠的协议,Web开发者调用的WebSocket的send函数在browser的实现中最终都是通过TCP的系统接口进行传输的。WebSocket和Http协议一样都属于应用层的协议,那么他们之间有没有什么关系呢?答案是肯定的,WebSocket在建立握手连接时,数据是通过http协议传输的,正如我们上一节所看到的“GET/chat HTTP/1.1”,这里面用到的只是http协议一些简单的字段。但是在建立连接之后,真正的数据传输阶段是不需要http协议参与的。

    具体关系可以参考下图:






    WebSocket(5)-- WebSocket Server

    如果要搭建一个Web服务器,我们会有很多选择,市场上也有很多成熟的产品供我们应用,比如开源的Apache,安装后只需简单的配置(或者默认配置)就可以工作了。但是如果想搭建一个WebSocket服务器就没有那么轻松了,因为WebSocket是一种新的通信协议,目前还是草案,没有成为标准,市场上也没有成熟的WebSocket服务器或者Library实现WebSocket协议,我们就必须自己动手写代码去解析和组装WebSocket的数据包。要这样完成一个WebSocket服务器,估计所有的人都想放弃,幸好的是市场上有几款比较好的开源库供我们使用,比如PyWebSocket,WebSocket-Node, LibWebSockets等等,这些库文件已经实现了WebSocket数据包的封装和解析,我们可以调用这些接口,这在很大程度上减少了我们的工作量。

    下面就简单介绍一下这些开源的库文件。

    1.     PyWebSocket

    PyWebSocket采用Python语言编写,可以很好的跨平台,扩展起来也比较简单,目前WebKit采用它搭建WebSocket服务器来做LayoutTest。

    我们可以获取源码通过下面的命令

    svn checkouthttp://pywebsocket.googlecode.com/svn/trunk/ pywebsocket-read-only

    更多的详细信息可以从http://code.google.com/p/pywebsocket/获取。

    2.     WebSocket-Node

    WebSocket-Node采用JavaScript语言编写,这个库是建立在nodejs之上的,对于熟悉JavaScript的朋友可参考一下,另外Html5和Web应用程序受欢迎的程度越来越高,nodejs也正受到广泛的关注。

    我们可以从下面的连接中获取源码

    https://github.com/Worlize/Websocket-Node

    3.     LibWebSockets

    LibWebSockets采用C/C++语言编写,可定制化的力度更大,从TCP监听开始到封包的完成我们都可以参与编程。

    我们可以从下面的命令获取源代码

    git clone git://git.warmcat.com/libwebsockets


    WebSocket(1)-- WebSocket API简介

    WebSocket是html5新增加的一种通信协议,目前流行的浏览器都支持这个协议,例如Chrome,Safari,Firefox,Opera,IE等等,对该协议支持最早的应该是chrome,从chrome12就已经开始支持,随着协议草案的不断变化,各个浏览器对协议的实现也在不停的更新。该协议还是草案,没有成为标准,不过成为标准应该只是时间问题了,从WebSocket草案的提出到现在已经有十几个版本了,目前最新的是版本17,所对应的协议版本号为13,目前对该协议支持最完善的浏览器应该是chrome,毕竟WebSocket协议草案也是Google发布的。

    1.     WebSocket API简介

    首先看一段简单的javascript代码,该代码调用了WebSockets的API。

    [javascript]  view plain copy 在CODE上查看代码片 派生到我的代码片
    1. var ws = new WebSocket(“ws://echo.websocket.org”);  
    2.   
    3. ws.onopen = function(){ws.send(“Test!”); };  
    4.   
    5. ws.onmessage = function(evt){console.log(evt.data);ws.close();};  
    6.   
    7. ws.onclose = function(evt){console.log(“WebSocketClosed!”);};  
    8.   
    9. ws.onerror = function(evt){console.log(“WebSocketError!”);};  

    这份代码总共只有5行,现在简单概述一下这5行代码的意义。

    第一行代码是在申请一个WebSocket对象,参数是需要连接的服务器端的地址,同http协议使用http://开头一样,WebSocket协议的URL使用ws://开头,另外安全的WebSocket协议使用wss://开头。

    第二行到第五行为WebSocket对象注册消息的处理函数,WebSocket对象一共支持四个消息 onopen, onmessage, onclose和onerror,当Browser和WebSocketServer连接成功后,会触发onopen消息;如果连接失败,发送、接收数据失败或者处理数据出现错误,browser会触发onerror消息;当Browser接收到WebSocketServer发送过来的数据时,就会触发onmessage消息,参数evt中包含server传输过来的数据;当Browser接收到WebSocketServer端发送的关闭连接请求时,就会触发onclose消息。我们可以看出所有的操作都是采用消息的方式触发的,这样就不会阻塞UI,使得UI有更快的响应时间,得到更好的用户体验。





    WebSocket(2)--为什么引入WebSocket协议

    Browser已经支持http协议,为什么还要开发一种新的WebSocket协议呢?我们知道http协议是一种单向的网络协议,在建立连接后,它只允许Browser/UA(UserAgent)向WebServer发出请求资源后,WebServer才能返回相应的数据。而WebServer不能主动的推送数据给Browser/UA,当初这么设计http协议也是有原因的,假设WebServer能主动的推送数据给Browser/UA,那Browser/UA就太容易受到攻击,一些广告商也会主动的把一些广告信息在不经意间强行的传输给客户端,这不能不说是一个灾难。那么单向的http协议给现在的网站或Web应用程序开发带来了哪些问题呢?

    让我们来看一个案例,现在假设我们想开发一个基于Web的应用程序去获取当前Web服务器的实时数据,例如股票的实时行情,火车票的剩余票数等等,这就需要Browser/UA与WebServer端之间反复的进行http通信,Browser不断的发送Get请求,去获取当前的实时数据。下面介绍几种常见的方式:

    1.     Polling


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

    2.     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个字节左右),这样的数据包在网络上周期性的传输,难免对网络带宽是一种浪费。

    通过上面的分析可知,要是在Browser能有一种新的网络协议,能支持客户端和服务器端的双向通信,而且协议的头部又不那么庞大就好了。WebSocket就是肩负这样一个使命登上舞台的。





    WebSocket(3)-- WebSocket协议简介

    WebSocket协议是一种双向通信协议,它建立在TCP之上,同http一样通过TCP来传输数据,但是它和http最大的不同有两点:1.WebSocket是一种双向通信协议,在建立连接后,WebSocket服务器和Browser/UA都能主动的向对方发送或接收数据,就像Socket一样,不同的是WebSocket是一种建立在Web基础上的一种简单模拟Socket的协议;2.WebSocket需要通过握手连接,类似于TCP它也需要客户端和服务器端进行握手连接,连接成功后才能相互通信。

    下面是一个简单的建立握手的时序图:

    这里简单说明一下WebSocket握手的过程。

    当Web应用程序调用new WebSocket(url)接口时,Browser就开始了与地址为url的WebServer建立握手连接的过程。

    1.     Browser与WebSocket服务器通过TCP三次握手建立连接,如果这个建立连接失败,那么后面的过程就不会执行,Web应用程序将收到错误消息通知。

    2.     在TCP建立连接成功后,Browser/UA通过http协议传送WebSocket支持的版本号,协议的字版本号,原始地址,主机地址等等一些列字段给服务器端。

    例如:

    [html]  view plain copy 在CODE上查看代码片 派生到我的代码片
    1. GET /chat HTTP/1.1  
    2. Host: server.example.com  
    3. Upgrade: websocket  
    4. Connection: Upgrade  
    5. Sec-WebSocket-Key:dGhlIHNhbXBsZSBub25jZQ==  
    6. Origin: http://example.com  
    7. Sec-WebSocket-Protocol: chat,superchat  
    8. Sec-WebSocket-Version: 13  

    3.     WebSocket服务器收到Browser/UA发送来的握手请求后,如果数据包数据和格式正确,客户端和服务器端的协议版本号匹配等等,就接受本次握手连接,并给出相应的数据回复,同样回复的数据包也是采用http协议传输。

    [html]  view plain copy 在CODE上查看代码片 派生到我的代码片
    1. HTTP/1.1 101 Switching Protocols  
    2. Upgrade: websocket  
    3. Connection: Upgrade  
    4. Sec-WebSocket-Accept:s3pPLMBiTxaQ9kYGzzhZRbK+xOo=  
    5. Sec-WebSocket-Protocol: chat  

    4.     Browser收到服务器回复的数据包后,如果数据包内容、格式都没有问题的话,就表示本次连接成功,触发onopen消息,此时Web开发者就可以在此时通过send接口想服务器发送数据。否则,握手连接失败,Web应用程序会收到onerror消息,并且能知道连接失败的原因。





    WebSocket(4)-- WebSocket与TCP、Http的关系

    WebSocket与http协议一样都是基于TCP的,所以他们都是可靠的协议,Web开发者调用的WebSocket的send函数在browser的实现中最终都是通过TCP的系统接口进行传输的。WebSocket和Http协议一样都属于应用层的协议,那么他们之间有没有什么关系呢?答案是肯定的,WebSocket在建立握手连接时,数据是通过http协议传输的,正如我们上一节所看到的“GET/chat HTTP/1.1”,这里面用到的只是http协议一些简单的字段。但是在建立连接之后,真正的数据传输阶段是不需要http协议参与的。

    具体关系可以参考下图:






    WebSocket(5)-- WebSocket Server

    如果要搭建一个Web服务器,我们会有很多选择,市场上也有很多成熟的产品供我们应用,比如开源的Apache,安装后只需简单的配置(或者默认配置)就可以工作了。但是如果想搭建一个WebSocket服务器就没有那么轻松了,因为WebSocket是一种新的通信协议,目前还是草案,没有成为标准,市场上也没有成熟的WebSocket服务器或者Library实现WebSocket协议,我们就必须自己动手写代码去解析和组装WebSocket的数据包。要这样完成一个WebSocket服务器,估计所有的人都想放弃,幸好的是市场上有几款比较好的开源库供我们使用,比如PyWebSocket,WebSocket-Node, LibWebSockets等等,这些库文件已经实现了WebSocket数据包的封装和解析,我们可以调用这些接口,这在很大程度上减少了我们的工作量。

    下面就简单介绍一下这些开源的库文件。

    1.     PyWebSocket

    PyWebSocket采用Python语言编写,可以很好的跨平台,扩展起来也比较简单,目前WebKit采用它搭建WebSocket服务器来做LayoutTest。

    我们可以获取源码通过下面的命令

    svn checkouthttp://pywebsocket.googlecode.com/svn/trunk/ pywebsocket-read-only

    更多的详细信息可以从http://code.google.com/p/pywebsocket/获取。

    2.     WebSocket-Node

    WebSocket-Node采用JavaScript语言编写,这个库是建立在nodejs之上的,对于熟悉JavaScript的朋友可参考一下,另外Html5和Web应用程序受欢迎的程度越来越高,nodejs也正受到广泛的关注。

    我们可以从下面的连接中获取源码

    https://github.com/Worlize/Websocket-Node

    3.     LibWebSockets

    LibWebSockets采用C/C++语言编写,可定制化的力度更大,从TCP监听开始到封包的完成我们都可以参与编程。

    我们可以从下面的命令获取源代码

    git clone git://git.warmcat.com/libwebsockets

    展开全文
  • 简介 WebSocket 是 HTML5 开始提供的一种在单个 TCP ... HTML5 定义的 WebSocket 协议,能更好的节省服务器资源和带宽,并且能够更实时地进行通讯 WebSocket 属性 Socket.readyState 只读属性readyState..

    简介

    • WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议
    • WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据
    • 浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输
    • HTML5 定义的 WebSocket 协议,能更好的节省服务器资源和带宽,并且能够更实时地进行通讯

    WebSocket 属性

    Socket.readyState

    只读属性 readyState 表示连接状态,可以是以下值:

    • 0 - 表示连接尚未建立。

    • 1 - 表示连接已建立,可以进行通信。

    • 2 - 表示连接正在进行关闭。

    • 3 - 表示连接已经关闭或者连接不能打开。

    Socket.bufferedAmount

    只读属性 bufferedAmount 已被 send() 放入正在队列中等待传输,但是还没有发出的 UTF-8 文本字节数。

    WebSocket 事件

    openSocket.onopen连接建立时触发
    messageSocket.onmessage客户端接收服务端数据时触发
    errorSocket.onerror通信发生错误时触发
    closeSocket.onclose连接关闭时触发

    WebSocket 方法 

    Socket.send()

    使用连接发送数据

    Socket.close()

    关闭连接

    实例demo

    Netty使用WebSocket协议实现服务器

    /**
     * ws服务器
     *
     * @author LionLi
     */
    public class WebSocketServer {
    
        public static void main(String[] args) throws Exception {
            // 创建 boss 和 worker 工作组
            EventLoopGroup bossGroup = new NioEventLoopGroup(1);
            EventLoopGroup workerGroup = new NioEventLoopGroup();
            try {
                ServerBootstrap serverBootstrap = new ServerBootstrap();
                serverBootstrap.group(bossGroup, workerGroup);
                // 主线程处理
                serverBootstrap.channel(NioServerSocketChannel.class);
                // 子线程业务处理
                serverBootstrap.childHandler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel ch) {
                        ChannelPipeline pipeline = ch.pipeline();
                        //因为基于http协议,使用http的编码和解码器
                        pipeline.addLast(new HttpServerCodec());
                        //是以块方式写,添加ChunkedWriteHandler处理器
                        pipeline.addLast(new ChunkedWriteHandler());
                        // http数据聚合器 用于将大数据量分段传输的数据 聚合
                        pipeline.addLast(new HttpObjectAggregator(8192));
                        // websocket协议处理器
                        pipeline.addLast(new WebSocketServerProtocolHandler("/ws"));
                        // 自定义的业务处理
                        pipeline.addLast(new WebSocketHandler());
                    }
                });
                // 启动服务器
                ChannelFuture channelFuture = serverBootstrap.bind(8088).sync();
                channelFuture.channel().closeFuture().sync();
            } finally {
                bossGroup.shutdownGracefully();
                workerGroup.shutdownGracefully();
            }
        }
    }

    自定义业务处理

    /**
     * 业务处理器
     *
     * @author LionLi
     */
    // TextWebSocketFrame 文本处理
    public class WebSocketHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {
    
        /**
         * 通道消息读取
         */
        @Override
        protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) {
            System.out.println("收到消息 " + msg.text());
            ctx.channel().writeAndFlush(new TextWebSocketFrame("收到消息 " + msg.text()));
        }
    
        /**
         * 连接初始化
         */
        @Override
        public void handlerAdded(ChannelHandlerContext ctx) {
            System.out.println("客户端连接:通道唯一id为 => " + ctx.channel().id().asLongText());
            System.out.println("客户端连接:通道不唯一id为 => " + ctx.channel().id().asShortText());
        }
    
        /**
         * 退出连接
         */
        @Override
        public void handlerRemoved(ChannelHandlerContext ctx) {
            System.out.println("客户端断开" + ctx.channel().id().asLongText());
        }
    
        /**
         * 异常处理
         */
        @Override
        public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
            System.out.println("客户端异常 " + cause.getMessage());
            //关闭连接
            ctx.close();
        }
    }

    测试

    使用页面进行测试

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Netty实现WebSocket服务器</title>
    </head>
    <body>
    <script>
        var socket;
        // 判断当前浏览器是否支持websocket
        if (window.WebSocket) {
            // 创建连接
            socket = new WebSocket("ws://localhost:8088/ws");
            // 消息监听
            socket.onmessage = function (ev) {
                var rt = document.getElementById("responseText");
                rt.value = rt.value + "\n" + ev.data;
            }
    
            // 连接初始化
            socket.onopen = function (ev) {
                var rt = document.getElementById("responseText");
                rt.value = "连接开启了.."
            }
    
            // 连接关闭
            socket.onclose = function (ev) {
                var rt = document.getElementById("responseText");
                rt.value = rt.value + "\n" + "连接关闭了.."
            }
        } else {
            alert("当前浏览器不支持websocket")
        }
    
        // 发送消息
        function send(message) {
            if (!window.socket) {
                return;
            }
            if (socket.readyState === WebSocket.OPEN) {
                socket.send(message)
            } else {
                alert("连接没有开启");
            }
        }
    </script>
    <form onsubmit="return false">
        <label>
            <textarea name="message" style="height: 300px; width: 300px"></textarea>
        </label>
        <input type="button" value="发送消息" onclick="send(this.form.message.value)">
        <label for="responseText"></label>
        <textarea id="responseText" style="height: 300px; width: 300px"></textarea>
        <input type="button" value="清空内容" onclick="document.getElementById('responseText').value=''">
    </form>
    </body>
    </html>

    启动服务器

    打开页面 自动连接服务器

    发送消息

    关闭页面

    项目已上传到gitee

    地址: netty-demo

    如果帮到您了,请帮忙点个star

    展开全文
  • WebSocket概念出来之前,如果页面要不停地显示最新的价格,那么必须不停地刷新页面,或者用一段js代码每隔几秒钟发消息询问服务器数据。 而使用WebSocket技术之后,当服务器有了新的数据,会主动通知浏览器。 ...

    概念

    在WebSocket概念出来之前,如果页面要不停地显示最新的价格,那么必须不停地刷新页面,或者用一段js代码每隔几秒钟发消息询问服务器数据。 
    而使用WebSocket技术之后,当服务器有了新的数据,会主动通知浏览器。

    优点

    1. 节约带宽。 不停地轮询服务端数据这种方式,使用的是http协议,head信息很大,有效数据占比低, 而使用WebSocket方式,头信息很小,有效数据占比高。
    2. 无浪费。 轮询方式有可能轮询10次,才碰到服务端数据更新,那么前9次都白轮询了,因为没有拿到变化的数据。 而WebSocket是由服务器主动回发,来的都是新数据。
    3. 实时性,考虑到服务器压力,使用轮询方式不可能很短的时间间隔,否则服务器压力太多,所以轮询时间间隔都比较长,好几秒,设置十几秒。 而WebSocket是由服务器主动推送过来,实时性是最高的

     

    服务器端代码:每创建一个浏览器会话就创建一个WebServer对象。 

    OnOpen 表示有浏览器链接过来的时候被调用
    OnClose 表示浏览器发出关闭请求的时候被调用
    OnMessage 表示浏览器发消息的时候被调用
    OnError 表示有错误发生,比如网络断开了等等
    sendMessage 用于向浏览器回发消息

    
    /**
     * @ServerEndpoint 注解是一个类层次的注解,它的功能主要是将目前的类定义成一个websocket服务器端,
     * 注解的值将被用于监听用户连接的终端访问URL地址,客户端可以通过这个URL来连接到WebSocket服务器端
     */
    @ServerEndpoint("/server")
    public class WebServer { //服务端
    	 //与某个客户端的连接会话,需要通过它来给客户端发送数据
        private Session session;
     
        @OnOpen
        public void onOpen(Session session){
            this.session = session;
            WebManger.add(this);    
        }
         
        public void sendMessage(String message) throws IOException{
            this.session.getBasicRemote().sendText(message);  //同步方法
        }
     
        @OnClose
        public void onClose(){
            WebManger.remove(this); 
        }
     
        @OnMessage
        public void onMessage(String message, Session session) {
            System.out.println("来自客户端的消息:" + message);
        }
     
        @OnError
        public void onError(Session session, Throwable error){
            System.out.println("发生错误");
            error.printStackTrace();
        }
    }

    再来一个负责管理每个浏览器会话(WebServer对象)的管理代码:

    //ServerManager 中维护了一个线程安全的集合servers, 用于因为浏览器发起连接请求而创建的Server. 
    public class WebManger {
    
    	public static List<WebServer> list=Collections.synchronizedList(new ArrayList<WebServer>());
    	
    	public static void broadCast(String message){
    		for(WebServer ws:list){
    			try {
    				ws.sendMessage(message);
    			} catch (IOException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			}
    		}
    	}
    	 public static int getTotal(){
    	        return list.size();
    	    }
    	    public static void add(WebServer server){
    	    	  list.add(server);
    	        System.out.println("有新连接加入! 当前总连接数是:"+ list.size());
    	      
    	    }
    	    public static void remove(WebServer server){
    	    	list.remove(server);
    	        System.out.println("有连接退出! 当前总连接数是:"+ list.size());
    	        
    	    }
    }
    

    最后再来一个次线程,让他不停的刷新数据,来达到服务器主动给浏览器发送数据的目的。

    //loadOnStartup标记为Servlet不是为了其被访问,而是为了便于伴随Tomcat一起启动
    @WebServlet(urlPatterns ="/MyThread",loadOnStartup=1)
    public class MyThread extends HttpServlet implements Runnable{
    	public void init(ServletConfig config){
    		 new Thread(this).start();
        }
    
    	@Override
    	public void run() {
    		int price=1000;
    		int count=1;
    		while (true) {
    			try {
    				Thread.sleep(2000);
    				float random = 1+(float) (Math.random()-0.5);
    				 
    				 count=WebManger.getTotal();
    				 if (count==0) {
    						count=1;
    					}
    				//随着人数改变价格
    				 price=(int)(random*price*count);
    				 //格式化字符串
    				 String messageFormat = "{\"price\":\"%d\",\"total\":%d}";
    		            String message = String.format(messageFormat, price,count);
    		            price=price/count;
    				 WebManger.broadCast(message);
    			} catch (InterruptedException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			}
    		}
    	}
         
       
    }
    

    附上前端代码:

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Insert title here</title>
    </head>
    <body>
    <div style="width:400px;margin:20px auto;border:1px solid lightgray;padding:20px;text-align:center;">
        		当前价格为:¥<span style="color:#FF7519" id="price">10000</span>
        		<div style="font-size:0.9em;margin-top:20px">当前人数为: <span id="total">1</span></div> 
        	</div>
    </body>
    <script type="text/javascript">
    var websocket=null;
    //判断浏览器是否支持websocket
    if('WebSocket' in window){
    	websocket=new WebSocket("ws://localhost:8080/WebSocket/server");
    	websocket.onopen=function(){
    		websocket.send("客户端连接成功");
    	}
    	websocket.onerror=function(){
    		websocket.send("客户端连接失败");
    	}
    	websocket.onclose=function(){
    		websocket.send("客户端连接关闭");
    	}
    	websocket.onmessage=function(e){
    		send(e.data);
    	}
    	//监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
    	window.onbeforeunload = function () {
    	    closeWebSocket();
    	}
    }
    else {
        alert('当前浏览器 Not support websocket')
    }
    //将消息显示在网页上
    function send(e) {
        var obj = eval("("+e+")");  
        document.getElementById('price').innerHTML =obj.price;
        document.getElementById('total').innerHTML = obj.total;
    }
    //关闭WebSocket连接
    function closeWebSocket() {
        websocket.close();
    }
    </script>
    </html>

     

    展开全文
  • 文章目录HTTPHTTP请求过程1....Websocket Server-Sent Events 通信协议 http http 握手:http --> websocket http 触发方式 Js Ajax Js Ajax 事件 事件 优点 兼容性好容错性强,实现简单 比短轮询节约资源
  • Erlang cowboy websocket 服务器

    万次阅读 2014-10-29 11:36:42
    Erlang可以用来实现一个websocket服务器。cowboy这样框架可以完成这个任务,是我们不必关注websocket协议的细节。
  • 前言最近,本人在自学WebSocket,然而在百度学习的过程中,发现要么按照文章的代码搭起来的WebSocket不能用,要么太过复杂,看的本菜鸟一愣一愣的,不知从何入手。所幸有大佬赐教,本人终于实现了一个简易的...
  • websocket简介: WebSocket协议是HTML5 开始提供的一种基于TCP的一种新的全双工通讯的网络通讯协议。它允许服务器主动发送信息给客户端。 和http协议的不同?? HTTP 协议是一种无状态的、无连接的、单向的...
  • WebSocket客户端和服务端实例源码

    千次下载 热门讨论 2015-08-14 13:30:01
    问题很明显,当客户端以固定频率向服务器端发送请求时,服务器端的数据可能并没有更新,带来很多无谓请求,浪费带宽,效率低下。 基于 Flash,AdobeFlash 通过自己的 Socket 实现完成数据交换,再利用 Flash 暴露出...
  • WebSocket 服务器4

    2016-10-19 17:40:00
    Java Websocket实例 Websocket2015-04-11 14:11:54 发布 您的评价: 4.4 收藏6收藏 ...轮询是在特定的的时间间隔(如每1秒),由浏览器对服务器发出HTTP...
  • 3.实现简易websocket服务器 4.websocket介绍 5.虚拟机安装 1.libwebsockets简介安装 https://blog.csdn.net/u013780605/article/details/79489183 (完全抄录原作者,抄录的目的是一为了一字不差看...
  • 到网上搜罗了一番资料后用 Node.js 实现了一个WebSocket协议服务器,倒也没有想象中那么复杂,除去注释语句和 console 语句后,大约 200 行代码左右。 本文分享了自已开发一个WebSocket服务端实现过程中需要的...
  • 本博文发表目的是,目前网上针对Websocket的资料太散乱,导致初学者的知识体系零零散散,学习困难加大。本博加以整理,并且实践。所用核心技术选型:Tomcat + Spring 4.0.3 + Mongodb(高并发数据库)+ SpringQueue...
  • 最近在开发一个游戏的客服系统,同一时间咨询问题的玩家多,为了保证服务器高可用,需要利用分布式,另外服务器宕机还需要玩家无感知重连,最关键的一点是如何实现服务器的高扩展性,即性能不足时,如何以最少的代价...
  • vue 使用WebSocket 连接

    2021-08-03 00:39:26
    WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。...
  • 5WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在 WebSocket API 中,...HTML5 定义的 WebSocket 协议,能更好的节省服务器资源和带宽,并且能够更实时地进行通讯。
  • 这篇文章可以说是高性能服务器开发的一个标志性文档,它讨论的就是单机为1万个连接提供服务这个问题,当时因为硬件和软件的**,单机1万还是 一个非常值得挑战的目标。但是时光荏苒,随着硬件和软件的飞速发展,单机1...
  • WebSocket 原理介绍及服务器搭建

    万次阅读 2015-03-25 18:33:03
    WebSocket(1)-- WebSocket API简介 WebSocket是html5新增加的一种通信协议,目前流行的浏览器都支持这个协议,例如Chrome,Safari,Firefox,Opera,IE等等,对该协议支持最早的应该是chrome,从chrome
  • websocket服务器推送

    2019-10-08 13:21:53
    WebSocket作为一种通信协议,属于服务器推送技术的一种,IE10+支持。 服务器推送技术不止一种,有短轮询、长轮询、WebSocket、Server-sent Events(SSE)等,他们各有优缺点: #短轮询长轮询Websocketsse ...
  • WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。 有很多网站为了实现推送技术,所用的技术都是 Ajax 轮询。轮询是在特定的的时间间隔(如每1秒...
  • websocket和webrtc笔记欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左...
  • 转载整理自https://www.zhihu.com/question/20215561 http://www.open-open.com/lib/view/open1435905714122.html...http://www.ibm.com/developerworks/cn/java/j-lo-WebSocket/ http://www.open-open.com/lib/view/o
  • HTML5 定义的 WebSocket 协议,能更好的节省服务器资源和带宽,并且能够更实时地进行通讯,图示如下: 1.2 WebSocket实例 WebSocket 协议本质上是一个基于 TCP 的协议。 为了建立一个 WebSocket 连接,客户端浏览器...
  • 本文是websocket客户端、服务器开发总结文档,记录从资料收集、代码编写到程序测试等需要注意的事项,帮助同样需要开发websocket的同学能快速完成开发任务。 一、websocket资料 1.什么是websocket WebSocket是一种...
  • WebSocket协议入门介绍

    2020-12-20 13:02:38
    目录WebSocket协议是什么WebSocket是应用层协议WebSocket是基于TCP的应用层协议,用于在C/S架构的应用中实现双向通信,关于WebSocket协议的详细规范和定义参见rfc6455。需要特别注意的是:虽然WebSocket协议在建立...
  • 它实现了浏览器与服务器全双工通信,能更好的节省服务器资源和带宽并达到实时通讯,它建立在 TCP 之上,同 HTTP 一样通过 TCP 来传输数据,但是它和 HTTP 最大不同是: WebSocket 是一种双向通信协议,在建立连接后...
  • 2.7、Netty可以实现WebSocket Netty是由jboss提供的一款开源框架,常用于搭建RPC中的TCP服务器和WebSocket服务器,甚至是类似Tomcat的web服务器,反正就是各种网络服务器,在处理高并发的项目中,功能丰富且性能...
  • 基于nodejs + websocket 搭建即时通讯应用

    万次阅读 多人点赞 2018-03-08 10:46:10
    如果说AJAX是像手机发短信...在以前你可能会使用AJAX进行轮询,这造成了服务器的多重压力,使用websocket,既可实现一次连接,保持通话的作用。而它有着广泛的应用场景,比如在线聊天室、在线客服系统、评论系统、...
  • 目录 [−] 服务器的参数调优 TCP/IP参数配置 最大文件描述符 应用运行时调优 OutOfMemory Killer 客户端的参数调优 ...服务器测试 ...Netty服务器 ...Spray服务器 ...这篇文章可以说是高性能服务器开发
  • 目前有很多WebSocket协议的服务器实现,然而相比RESTful HTTP方法,这些实现在带宽优化方面做的都略显不够,并非所有WebSocket服务器实现能提供同等程度的低延迟和可缩放性。 注意 – 相比Web服务器,WebSocket协议...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 7,920
精华内容 3,168
关键字:

websocket服务器带宽