2010-07-10 13 views
7

मैं एक साधारण वेबसाइकिल सर्वर को लागू करने के लिए अजगर का उपयोग कर रहा हूं। मैं जिस हैंडशेक का उपयोग कर रहा हूं वह http://en.wikipedia.org/w/index.php?title=WebSockets&oldid=372387414 से आता है।वेबस्केट हैंडशेक समस्या

हाथ मिलाना ही काम करने के लिए लगता है, लेकिन जब मैं भेज हिट, मैं एक जावास्क्रिप्ट त्रुटि मिलती है:

Uncaught Error: INVALID_STATE_ERR: DOM Exception 11

यहाँ एचटीएमएल है:

<!doctype html> 
<html> 
    <head> 
     <title>ws_json</title> 

    </head> 
    <body onload="handleLoad();" onunload="handleUnload();"> 
     <input type="text" id='input' /> 
     <input type="button" value="submit" onclick="handleSubmit()" /> 
     <div id="display"></div> 

     <script type="text/javascript"> 
      function showmsg(str){ 
       display = document.getElementById("display"); 
       display.innerHTML += "<p>" + str + "</p>"; 
      } 

      function send(str){ 
       ws.send(str.length); 
       ws.send(str); 
      } 

      function handleSubmit(){ 
       input = document.getElementById('input'); 
       send(input.value); 
       input.focus(); 
       input.value = ''; 
      } 

      function handleLoad(){ 
       ws = new WebSocket("ws://localhost:8888/"); 
       ws.onopen = function(){ 
        showmsg("websocket opened."); 
       } 

       ws.onclose = function(){ 
        showmsg("websocket closed."); 
       } 
      } 

      function handleUnload(){ 
       ws.close(); 
      } 
     </script> 
    </body> 
</html> 

और यहाँ अजगर कोड है:

import socket 
import threading 
import json 

PORT = 8888 
LOCATION = "localhost:8888" 

def handler(s): 

    print " in handler " 

    ip, _ = s.getpeername() 
    print "New connection from %s" % ip 
    request = s.recv(1024) 

    print "\n%s\n" % request 
    print s.getpeername() 

    # send response 
    response = "HTTP/1.1 101 Web Socket Protocol Handshake\r\n" 
    response += "Upgrade: WebSocket\r\n" 
    response += "Connection: Upgrade\r\n" 
    try: 
     peername = s.getpeername() 
     response += "Sec-WebSocket-Origin: http://%s\r\n" % peername[0] # % request[request.index("Origin: ")+8:-4] 
    except ValueError: 
     print "Bad Request" 
     raise socket.error 
    response += "Sec-WebSocket-Location: ws://%s\r\n" % LOCATION 
    response += "Sec-WebSocket-Protocol: sample" 
    response = response.strip() + "\r\n\r\n" 

    print response 
    s.send(response) 

    while True: 
     length = s.recv(1) 
     print length 
     if not length: 
      break 
     length = int(length) 
     print "Length: %i" % length 
     data = s.recv(length) 
     print "Received: %s" % data 
     print "" 

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 
s.bind(('localhost', PORT)) 
s.listen(5) 

print "server is running..." 
while True: 
    sock, addr = s.accept() 
    threading.Thread(target=handler, args=(sock,)).start() 

क्या कोई जानता है कि मैं यहां क्या गलत कर रहा हूं?

+0

मैं वेबस्केट कक्षा के बिना आपके कोड का परीक्षण नहीं कर सकता। यह कहां परिभाषित किया गया है? फ़ायरफ़ॉक्स 3.6.3 को यह नहीं पता था कि यह क्या है। – Nathan

+0

क्रोम देव के पास है, और फ़ायरफ़ॉक्स 4 को यह माना जाता है। – lowerkey

+0

यदि आपके पास 100 प्रतिनिधि नहीं हैं तो आपने एक बक्षीस कैसे दिया? – Nathan

उत्तर

6

मैं फ़ायरफ़ॉक्स 4 पर अपने कोड का परीक्षण किया और भेजें दबाने पर एक ही त्रुटि मिली, फिर भी है कि इससे पहले कि मैं

Firefox can't establish a connection to the server at ws://localhost:8888/.

मिला जो शायद यही वजह है WebSocket वस्तु नष्ट हो गया। मुझे संदेह है कि आपके हैंडशेक प्रतिक्रिया में कुछ गुम है, इसलिए फ़ायरफ़ॉक्स सॉकेट बंद कर रहा है।

पर WebSockets विकिपीडिया लेख से:

The Sec-WebSocket-Key1 and Sec-WebSocket-Key2 fields and the eight bytes after the fields are random tokens which the server uses to construct a 16 byte token at the end of its handshake to prove that it has read the client's handshake.

आपका सर्वर की प्रतिक्रिया तल पर इस विशेष नंबर नहीं है, तो मुझे लगता है कि हम यह पता लगाने की कि यह कैसे उत्पन्न करने के लिए की जरूरत है, और यह भी शामिल है।

संपादित करें: कैसे उस नंबर

कुंजी 1, कुंजी 2 के साथ शुरू की सुविधा देता है, और हाथ मिलाना के अंत में 8 बाइट्स उत्पन्न करने के लिए

key1 = "18x 6]8vM;54 *(5: { U1]8 z [ 8" 
key2 = "1_ tx7X d < nw 334J702) 7]o}` 0" 
end8 = "Tm[K T2u" 

हम एक नंबर की अनदेखी करके प्रत्येक कुंजी के लिए बनाने के प्रत्येक चरित्र जो अंक 0-9 नहीं है। अजगर में:

def numFromKey(key): 
    return int(filter(lambda c: c in map(str,range(10)),key)) 

अगले हम मूल कुंजी स्ट्रिंग में रिक्त स्थान की संख्या से उस नंबर को विभाजित है, इसलिए यहां एक एक समारोह है कि एक स्ट्रिंग में रिक्त स्थान में गिना जाता है है।

def spacesIn(key): 
    return len(filter(lambda c: c==' ',key)) 

दो कुंजियों से उत्पन्न नंबर दिए गए हैं:

pkey1 = numFromKey(key1)/spacesIn(key1) 
pkey2 = numFromKey(key2)/spacesIn(key2) 

अब हम pkey1, pkey2, और end8 के बाइट्स को श्रेणीबद्ध करने की जरूरत है। संसाधित कुंजी को 32 बिट बिग-एंडियन संख्याओं के रूप में प्रदर्शित करने की आवश्यकता होती है।

from struct import pack 
catstring = pack('>L',pkey1) + pack('>L',pkey2) + end8 

फिर हम उन बाइट्स की MD5 हैश ले जादुई संख्या है कि हम हाथ मिलाना

import md5 
magic = md5.new(catstring).digest() 

Thats के अंत पर हमले पाने के लिए मैं यह काम करता है कम से कम

+0

जानकारी के लिए धन्यवाद, कभी भी यह पता नहीं लगा होगा। मैंने इसे Google पर पाया: http://golang.org/src/pkg/websocket/server.go यह वर्णन करता है कि कुंजी कैसे उत्पन्न करें। जैसा कि हम बोलते हैं इसे समझने पर काम करना। – lowerkey

+0

यहां हैंडशेक का एक बेहतर विवरण है: http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol-76#page-7 – lowerkey

+1

मैं इसी तरह के समाधान पर आया, लेकिन मुझे परिणामों के एन्कोडिंग में समस्याएं आ रही हैं utf-8 में md5 एल्गोरिदम। – lowerkey

0

के रूप में लगता है संस्करण 8 की, इस प्रोटोकॉल हटा दिया गया है कृपया देखें:

http://tools.ietf.org/id/draft-ietf-hybi-thewebsocketprotocol-12.txt

प्रोटोकॉल के नए संस्करण के लिए

+0

संकेत के लिए धन्यवाद। यह थोड़ी देर हो गया है ... – lowerkey

संबंधित मुद्दे