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>  
    

      

  • 相关阅读:
    js学习(三)对象与事件
    js学习(二)
    js学习(一)
    SSM+Redis结构框架及概述
    javaBean、EJB、POJO
    flex布局时的居中问题
    layui后台管理系统的坑
    基于element的模糊查询
    vue数组的运用
    uni-app 图片上传(uploadFile)
  • 原文地址:https://www.cnblogs.com/liujiliang/p/7903913.html
Copyright © 2011-2022 走看看