ASP源码.NET源码PHP源码JSP源码JAVA源码DELPHI源码PB源码VC源码VB源码Android源码

websocket websocket介绍

来源:网络整理     时间:2017-12-06     关键词:websocket

本篇文章主要介绍了"websocket websocket介绍",主要涉及到websocket方面的内容,对于Pythonjrs看球网直播吧_低调看直播体育app软件下载_低调看体育直播感兴趣的同学可以参考一下: websocket应用手动实现的websocket你所见过的websocket你一定见过在网站中,有一个游客聊天的聊天框,比如人人影视。这个聊天框是如何实现即时...

websocket应用

手动实现的websocket

你所见过的websocket

你一定见过在网站中,有一个游客聊天的聊天框,比如人人影视。这个聊天框是如何实现即时通讯的呢,就是用到了websocket

你可以打开浏览器的network,会看到有个ws://xxxxx,这就代表了是websocket做的

那么什么是websocket?

websocket就是一套协议。

看名字,虽然有个websocket,但他和http协议一样,也要走socket。

不同的是:http是短连接,处理完一个请求就断开;

? websocket是连上就不断开,一直不断开,属于双工通道,服务端可以主动给客户端推送消息,客户端也可以主动给服务端推送消息

当某一个客户端发送一条消息,服务端接收以后,再推送给所有的客户端,所以才会呈现出所有人都在即时通讯的效果

服务端当然就是我们写的程序了,那客户端是浏览器,所以还需要浏览器支持才行。不要以为浏览器是都支持的,如果所有人都用chrome,前端开发工程师估计就没什么工作了。还有,如果所有的浏览器都支持,腾讯的webQQ,web微信,也不会使用长轮询来做这个事了。

来看一下具体的代码实现

import socket
import base64
import hashlib

def get_headers(data):
    """    将请求头格式化成字典    :param data:    :return:    """
    header_dict = {}
    data =str(data, encoding='utf-8')

    for i in data.split('\r\n'):
        print(i)
    header, body = data.split('\r\n\r\n', 1)
    header_list = header.split('\r\n')
    for i inrange(0, len(header_list)):
        if i ==0:
            iflen(header_list[i].split(' ')) ==3:
                header_dict['method'], header_dict['url'], header_dict['protocol'] = header_list[i].split(' ')
        else:
            k, v = header_list[i].split(':', 1)
            header_dict[k] = v.strip()
    return header_dict

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind(('127.0.0.1', 8002))
sock.listen(5)

conn, address = sock.accept()
data = conn.recv(1024)

headers = get_headers(data)  # 提取请求头信息# 对请求头中的sec-websocket-key进行加密
response_tpl ="HTTP/1.1 101 Switching Protocols\r\n"\"Upgrade:websocket\r\n"\"Connection: Upgrade\r\n"\"Sec-WebSocket-Accept: %s\r\n"\"WebSocket-Location: ws://%s%s\r\n\r\n"magic_string ='258EAFA5-E914-47DA-95CA-C5AB0DC85B11'#固定的,魔法字符串就是这个字符串
value = headers['Sec-WebSocket-Key'] + magic_string
ac = base64.b64encode(hashlib.sha1(value.encode('utf-8')).digest()) #把返回消息加密response_str = response_tpl % (ac.decode('utf-8'), headers['Host'], headers['url'])
# 响应【握手】信息
conn.send(bytes(response_str, encoding='utf-8'))

info = conn.recv(8096)

#下面是对浏览器发来的消息解密的过程
payload_len = info[1] &127if payload_len ==126:
    extend_payload_len = info[2:4]
    mask = info[4:8]
    decoded = info[8:] # 数据elif payload_len ==127:
    extend_payload_len = info[2:10]
    mask = info[10:14]
    decoded = info[14:]
else:
    extend_payload_len =None
    mask = info[2:6]
    decoded = info[6:]

bytes_list =bytearray()
for i inrange(len(decoded)):       #上面解密的最终结果,就是拿到这个decode,就是浏览器发来的真实的数据(加密的)
    chunk = decoded[i] ^ mask[i %4]    #按位异或
    bytes_list.append(chunk)

body =str(bytes_list, encoding='utf-8')
print(body)

客户端向服务端发送的请求里,有Sec-WebSocket-Key这样一个key,服务端回消息的时候,就要拿到这个key,加密后再发给浏览器,浏览器会判断自己加密后的值,与浏览器处理的是否一致,一致才能连接。加密的方式,用到一个magic_string,其实就是一段固定的字符串258EAFA5-E914-47DA-95CA-C5AB0DC85B11,加密后打包发给浏览器,浏览器验证通过后就可以通讯了,再来看看客户端:

客户端就直接用浏览器运行这个html文件就行

html><> lang="en"><> charset="UTF-8">Title<> rel="stylesheet" href="dist/css/bootstrap.css">
<> type="text" id="txt"/><> type="button" id="btn" value="提交" /span>"sendMsg();"/><> type="button" id="close" value="关闭连接" /span>"closeConn();"/>
<> id="content">
<> type="text/javascript">var socket =newWebSocket("ws://127.0.0.1:8002");socket.onopen=function () {/* 与服务器端连接成功后,自动执行 */var newTag =document.createElement('div');newTag.innerHTML="【连接成功】";document.getElementById('content').appendChild(newTag);};socket.onmessage=function (event) {/* 服务器端向客户端发送数据时,自动执行 */var response =event.data;var newTag =document.createElement('div');newTag.innerHTML= response;document.getElementById('content').appendChild(newTag);};socket.onclose=function (event) {/* 服务器端主动断开连接时,自动执行 */var newTag =document.createElement('div');newTag.innerHTML="【关闭连接】";document.getElementById('content').appendChild(newTag);};functionsendMsg() {var txt =document.getElementById('txt');socket.send(txt.value);txt.value="";}functioncloseConn() {socket.close();var newTag =document.createElement('div');newTag.innerHTML="【关闭连接】";document.getElementById('content').appendChild(newTag);}</script><> type="text/javascript">$(function () {wsUpdater.start();});var wsUpdater ={socket:null,uid:null,start:function() {var url ="ws://192.168.16.200:8009/chat";wsUpdater.socket=newWebSocket(url);wsUpdater.socket.onmessage=function(event) {if(wsUpdater.uid){wsUpdater.showMessage(event.data);}else{wsUpdater.uid=event.data;}}},showMessage:function(content) {$('#container').append(content);}};functionsendMsg() {var msg ={uid:wsUpdater.uid,message:$("#txt").val() };wsUpdater.socket.send(JSON.stringify(msg));}</script>></html>

原理都一样,但是用tornado实现起来,就清爽多了。

ps:再说一下腾讯的长轮询,如果你登录webQQ,或者web微信,你可以在network里面找到 pending的字样,这就是表示是使用的长轮询。

长轮询与轮询的区别就是:

? 轮询是过来以后看到没消息就立马去走了,但是长轮询不会立马走,而是在这等30秒(约定的时间)之后,如果一直没有消息,才返回,下一次来在等30秒,直到有消息了,这样有个缺点就是,拿到的消息并不是即时的。那腾讯这么大的公司,为什么不用性能更好的websocket呢?原因就是他是个大公司,必须要考虑兼容性,必须要保证所有的浏览器都能使用才行。

你可以从这里拿到完整 的示例代码

https://github.com/zEllis/websocket_demo

以上就介绍了websocket websocket介绍,包括了websocket方面的内容,希望对Pythonjrs看球网直播吧_低调看直播体育app软件下载_低调看体育直播有兴趣的朋友有所帮助。

本文网址链接:http://www.codes51.com/article/detail_4517690.html

websocket相关图片

websocket相关文章