zoukankan      html  css  js  c++  java
  • websocket实现简单的通信

    websocket server端

    #coding=utf8  
    #!/usr/bin/python  
      
      
    import struct,socket  
    import hashlib  
    import threading,random  
    import time  
    import struct  
    from base64 import b64encode, b64decode  
      
      
    connectionlist = {}  
    g_code_length = 0  
    g_header_length = 0  
      
      
    def hex2dec(string_num):  
        return str(int(string_num.upper(), 16))  
      
      
      
      
    def get_datalength(msg):  
        global g_code_length  
        global g_header_length      
          
        print (len(msg))  
        g_code_length = ord(msg[1]) & 127  
        received_length = 0;  
        if g_code_length == 126:  
            #g_code_length = msg[2:4]  
            #g_code_length = (ord(msg[2])<<8) + (ord(msg[3]))  
            g_code_length = struct.unpack('>H', str(msg[2:4]))[0]  
            g_header_length = 8  
        elif g_code_length == 127:  
            #g_code_length = msg[2:10]  
            g_code_length = struct.unpack('>Q', str(msg[2:10]))[0]  
            g_header_length = 14  
        else:  
            g_header_length = 6  
        g_code_length = int(g_code_length)  
        return g_code_length  
              
    def parse_data(msg):  
        global g_code_length  
        g_code_length = ord(msg[1]) & 127  
        received_length = 0;  
        if g_code_length == 126:  
            g_code_length = struct.unpack('>H', str(msg[2:4]))[0]  
            masks = msg[4:8]  
            data = msg[8:]  
        elif g_code_length == 127:  
            g_code_length = struct.unpack('>Q', str(msg[2:10]))[0]  
            masks = msg[10:14]  
            data = msg[14:]  
        else:  
            masks = msg[2:6]  
            data = msg[6:]  
      
      
        i = 0  
        raw_str = ''  
      
      
        for d in data:  
            raw_str += chr(ord(d) ^ ord(masks[i%4]))  
            i += 1  
      
      
        print (u"总长度是:%d" % int(g_code_length))      
        return raw_str    
      
      
    def sendMessage(message):  
        global connectionlist  
          
        message_utf_8 = message.encode('utf-8')  
        for connection in connectionlist.values():  
            back_str = []  
            back_str.append('x81')  
            data_length = len(message_utf_8)  
      
      
            if data_length <= 125:  
                back_str.append(chr(data_length))  
            elif data_length <= 65535 :  
                back_str.append(struct.pack('b', 126))  
                back_str.append(struct.pack('>h', data_length))  
                #back_str.append(chr(data_length >> 8))  
                #back_str.append(chr(data_length & 0xFF))  
                #a = struct.pack('>h', data_length)  
                #b = chr(data_length >> 8)  
                #c = chr(data_length & 0xFF)  
            elif data_length <= (2^64-1):  
                #back_str.append(chr(127))  
                back_str.append(struct.pack('b', 127))  
                back_str.append(struct.pack('>q', data_length))  
                #back_str.append(chr(data_length >> 8))  
                #back_str.append(chr(data_length & 0xFF))        
            else :  
                    print (u'太长了')          
            msg = ''  
            for c in back_str:  
                msg += c;  
            back_str = str(msg)   + message_utf_8#.encode('utf-8')      
            #connection.send(str.encode(str(u"x00%sxFF
    
    " % message))) #这个是旧版  
            #print (u'send message:' +  message)  
            if back_str != None and len(back_str) > 0:  
                print (back_str)  
                connection.send(back_str)  
      
      
    def deleteconnection(item):  
        global connectionlist  
        del connectionlist['connection'+item]  
      
      
    class WebSocket(threading.Thread):#继承Thread  
      
      
        GUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"  
      
      
        def __init__(self,conn,index,name,remote, path="/"):  
            threading.Thread.__init__(self)#初始化父类Thread  
            self.conn = conn  
            self.index = index  
            self.name = name  
            self.remote = remote  
            self.path = path  
            self.buffer = ""  
            self.buffer_utf8 = ""  
            self.length_buffer = 0  
        def run(self):#重载Thread的run  
            print('Socket%s Start!' % self.index)  
            headers = {}  
            self.handshaken = False  
      
      
            while True:  
                if self.handshaken == False:  
                    print ('Socket%s Start Handshaken with %s!' % (self.index,self.remote))  
                    self.buffer += bytes.decode(self.conn.recv(1024))  
      
      
                    if self.buffer.find('
    
    ') != -1:  
                        header, data = self.buffer.split('
    
    ', 1)  
                        for line in header.split("
    ")[1:]:  
                            key, value = line.split(": ", 1)  
                            headers[key] = value  
      
      
                        headers["Location"] = ("ws://%s%s" %(headers["Host"], self.path))  
                        key = headers['Sec-WebSocket-Key']  
                        token = b64encode(hashlib.sha1(str.encode(str(key + self.GUID))).digest())  
      
      
                        handshake="HTTP/1.1 101 Switching Protocols
    "
                            "Upgrade: websocket
    "
                            "Connection: Upgrade
    "
                            "Sec-WebSocket-Accept: "+bytes.decode(token)+"
    "
                            "WebSocket-Origin: "+str(headers["Origin"])+"
    "
                            "WebSocket-Location: "+str(headers["Location"])+"
    
    "  
      
      
                        self.conn.send(str.encode(str(handshake)))  
                        self.handshaken = True    
                        print ('Socket %s Handshaken with %s success!' %(self.index, self.remote))    
                        sendMessage(u'Welcome, ' + self.name + ' !')    
                        self.buffer_utf8 = ""  
                        g_code_length = 0                      
      
      
                else:  
                    global g_code_length  
                    global g_header_length  
                    mm=self.conn.recv(128)  
                    if len(mm) <= 0:  
                        continue  
                    if g_code_length == 0:  
                        get_datalength(mm)  
                    #接受的长度  
                    self.length_buffer = self.length_buffer + len(mm)  
                    self.buffer = self.buffer + mm  
                    if self.length_buffer - g_header_length < g_code_length :  
                        continue  
                    else :  
                        self.buffer_utf8 = parse_data(self.buffer) #utf8                  
                        msg_unicode = str(self.buffer_utf8).decode('utf-8', 'ignore') #unicode  
                        if msg_unicode=='quit':  
                            print (u'Socket%s Logout!' % (self.index))  
                            nowTime = time.strftime('%H:%M:%S',time.localtime(time.time()))  
                            sendMessage(u'%s %s say: %s' % (nowTime, self.remote, self.name+' Logout'))                        
                            deleteconnection(str(self.index))  
                            self.conn.close()  
                            break #退出线程  
                        else:  
                            #print (u'Socket%s Got msg:%s from %s!' % (self.index, msg_unicode, self.remote))  
                            nowTime = time.strftime(u'%H:%M:%S',time.localtime(time.time()))  
                            sendMessage(u'%s %s say: %s' % (nowTime, self.remote, msg_unicode))    
                        #重置buffer和bufferlength  
                        self.buffer_utf8 = ""  
                        self.buffer = ""  
                        g_code_length = 0  
                        self.length_buffer = 0  
                self.buffer = ""  
      
      
    class WebSocketServer(object):  
        def __init__(self):  
            self.socket = None  
        def begin(self):  
            print( 'WebSocketServer Start!')  
            self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  
            self.socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)  
            self.socket.bind(("0.0.0.0",12345))  
            self.socket.listen(50)  
      
      
            global connectionlist  
      
      
            i=0  
            while True:  
                connection, address = self.socket.accept()  
      
      
                username=address[0]       
                newSocket = WebSocket(connection,i,username,address)  
                newSocket.start() #开始线程,执行run函数  
                connectionlist['connection'+str(i)]=connection  
                i = i + 1  
      
      
    if __name__ == "__main__":  
        server = WebSocketServer()  
        server.begin() 
    

      

    websocket client 浏览器

    <!DOCTYPE html>
    <html>  
    <head>  
        <title>WebSocket</title>  
      
        <style>  
            html, body {  
                font: normal 0.9em arial, helvetica;  
            }  
      
            #log {  
                 440px;  
                height: 200px;  
                border: 1px solid #7F9DB9;  
                overflow: auto;  
            }  
      
            #msg {  
                 330px;  
            }  
        </style>  
      
        <script>  
            var socket;  
      
            function init() {  
                var host = "ws://127.0.0.1:12345/";
                try {  
                    socket = new WebSocket(host);  
                    socket.onopen = function (msg) {  
                        log('Connected');  
                    };  
                    socket.onmessage = function (msg) {  
                        log(msg.data);  
                    };  
                    socket.onclose = function (msg) {  
                        log("Lose Connection!");  
                    };  
                }  
                catch (ex) {  
                    log(ex);  
                }  
                $("msg").focus();  
            }  
      
            function send() {  
                var txt, msg;  
                txt = $("msg");  
                msg = txt.value;  
                if (!msg) {  
                    alert("Message can not be empty");  
                    return;  
                }  
                txt.value = "";  
                txt.focus();  
                try {  
                    socket.send(msg);  
                } catch (ex) {  
                    log(ex);  
                }  
            }  
      
            window.onbeforeunload = function () {  
                try {  
                    socket.send('quit');  
                    socket.close();  
                    socket = null;  
                }  
                catch (ex) {  
                    log(ex);  
                }  
            };  
      
      
            function $(id) {  
                return document.getElementById(id);  
            }  
            function log(msg) {  
                $("log").innerHTML += "<br>" + msg;  
            }  
            function onkey(event) {  
                if (event.keyCode == 13) {  
                    send();  
                }  
            }  
        </script>  
      
    </head>  
      
      
    <body onload="init()">  
    <h3>WebSocket</h3>  
    <br><br>  
      
    <div id="log"></div>  
    <input id="msg" type="textbox" onkeypress="onkey(event)"/>  
    <button onclick="send()">发送</button>  
    </body>  
      
    </html>  
    

      

  • 相关阅读:
    HYSBZ 3813 奇数国
    HYSBZ 4419 发微博
    HYSBZ 1079 着色方案
    HYSBZ 3506 排序机械臂
    HYSBZ 3224 Tyvj 1728 普通平衡树
    Unity 3D,地形属性
    nginx 的naginx 种包含include关键字
    Redis 出现NOAUTH Authentication required解决方案
    mysql 8.0出现 Public Key Retrieval is not allowed
    修改jar包里的源码时候需要注意的问题
  • 原文地址:https://www.cnblogs.com/liujiliang/p/7903913.html
Copyright © 2011-2022 走看看