Welcome to the Pycom forum Forum
    • \[\[global:header.categories\]\]
    • \[\[global:header.recent\]\]
    • \[\[global:header.tags\]\]
    • \[\[global:header.popular\]\]
    • Login

    Explore Pybytes | Official Documentation | Report a Firmware Bug/Issue | GitHub

    Thread WebSocketServer

    Scheduled Pinned Locked Moved LoPy
    threadwebsocketstack overflowlopy
    5 Posts 3 Posters 3.2k Views 4 Watching
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • J Offline
      jobbyworld
      last edited by jobbyworld

      Dear pythonist,
      Have trouble for writing threaded WebSocketEchoServer :
      Code working without thread.
      Code working with thread but hang somme times with
      "ERROR A stack overflow in task Thread has been detected. "

      If anyone knows more me about thread and how to debug

      Thanks for any help
      cheers !!
      Here my file "wsServer.py" :

      
      from hashlib import sha1
      
      from ubinascii import b2a_base64 as b64encode
      import sys
       
      from time import sleep_ms
      import micropython
      import socket
      import struct
      import ujson
      from struct import unpack,calcsize
      from network import Server
      from _thread import *
      micropython.alloc_emergency_exception_buf(100)
      
      FIN    = 0x80
      OPCODE = 0x0f
      MASKED = 0x80
      PAYLOAD_LEN = 0x7f
      PAYLOAD_LEN_EXT16 = 0x7e
      PAYLOAD_LEN_EXT64 = 0x7f
      
      OPCODE_TEXT = 0x01
      CLOSE_CONN  = 0x8
      
      
      
      def handshake(client):
      	header=b""
      	while header.find(b'\r\n\r\n') == -1:
      		header += client.recv(16)
      	#print(header.decode())
      	lines = header.split(b"\r\n")
      	d=dict()
      	for line in lines[1:]:
      		if not line :continue
      		header,value = line.split(b": ",1)
      		d[header]=value
      
      	key = d[b'Sec-WebSocket-Key'].decode()
      
      	# compute Response Key
      	GUID = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11'
      	hash = sha1(key.encode() + GUID.encode())
      	d=hash.digest()
      	response_key = b64encode(d).strip().decode('ASCII')
      	template='HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: %s\r\n\r\n'
      	handshake=template%response_key
      	client.send(handshake.encode())
      	print("handshake Done")
      
      def sendMessage(client,message):
      	global lock
      	header  = bytearray()
      	payload = message.encode('UTF-8')
      	payload_length = len(payload)
      	if payload_length <= 125:
      		header.append(FIN | OPCODE_TEXT)
      		header.append(payload_length)
      	#with lock:
      	client.send(header + payload)
      
      def readMessage(client,callback=lambda msg:print("receveid ",msg)):
      	b1, b2 = client.recv(2)
      	fin    = b1 & FIN
      	opcode = b1 & OPCODE
      	masked = b2 & MASKED
      	payload_length = b2 & PAYLOAD_LEN
      	if payload_length == 126:
      		#with lock:
      		payload_length = struct.unpack(">H", client.recv(2))[0]
      	elif payload_length == 127:
      		#with lock:
      		payload_length = struct.unpack(">Q", client.recv(8))[0]
      	#with lock:
      	masks = client.recv(4)
      	decoded = ""
      	#with lock:
      	data = client.recv(payload_length)
      	for char in data:
      		char ^= masks[len(decoded) % 4]
      		decoded += chr(char)
      
      	if callback:
      		callback(decoded)
      	return decoded
      
      
      
      	
      
      
      def thread_serve():
      	s=Server()
      	s.deinit()
      	start_new_thread(echoserve, (False,))
      
      def echoserve(blocking=True,port =9001):
      	lock = allocate_lock()
      	global sock
      	global serving
      	sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
      	sock.bind(("", port))
      	sock.listen()
      	sock.setblocking(blocking)
      	global client
      	print("waiting client at",port)
      	serving=True
      	while serving:
      		client = None
      		try:
      			with lock:
      				client, address = sock.accept()  
      		except socket.error as e:
      			if e.args[0]==11:
      				sleep_ms(1000)
      				continue
      			else:
      				print(e)
      		print("client connected ",address)
      		handshake(client)
      		break
      	print("End Thread Serving")
      	#client, address = sock.accept()  
      	client.setblocking(blocking)
      	while serving:
      		try:
      			with lock:
      				data = readMessage(client,None)
      		except ValueError:
      			sleep_ms(200)
      			continue
      		if data:
      			with lock:
      				sendMessage(client,"Echo "+data)
      			if data=="quit":
      				break
      	print("End Thread Listening")
      
      
      
      def stop():
      	global sock
      	global serving	
      	global client
      	serving=False
      	sock.close()
      	client.close()
      	s=Server()
      
      

      And the result error :

      >>> execfile("wsServer.py")
      >>> thread_serve()
      >>> waiting client at 9001
      client connected  ('192.168.4.2', 55233)
      handshake Done
      End Thread Serving
       
      >>> ***ERROR*** A stack overflow in task Thread has been detected.
      ***ERROR*** A stack overflow in task Thread has been detected.
      ***ERROR*** A stack overflow in task Thread has been detected.
      ***ERROR*** A stack overflow in task Thread has been detected.
      ***ERROR*** A stack overflow in task Thread has been detected.
      ***ERROR*** A stack overflow in task Thread has been detected.
      ***ERROR*** A stack overflow in task Thread has been detected.
      ***ERROR*** A stack overflow in task Thread has been detected.
      ***ERROR*** A stack overflow in task Thread has been detected.
      

      My code works without thread.
      here client.html for testing, change ip according to your lopy ip :

      <html>
      <head>
        <title>Simple client</title>
      
        <script type="text/javascript">
      
          var ws;
          
          function init() {
      
            // Connect to Web Socket
            ws = new WebSocket("ws://192.168.4.1:9001/");
      
            // Set event handlers.
            ws.onopen = function() {
              output("onopen");
            };
            
            ws.onmessage = function(e) {
              // e.data contains received string.
              output("onmessage: " + e.data);
            };
            
            ws.onclose = function() {
              output("onclose");
            };
      
            ws.onerror = function(e) {
              output("onerror");
              console.log(e)
            };
      
          }
          
          function onSubmit() {
            var input = document.getElementById("input");
            // You can send message to the Web Socket using ws.send.
            ws.send(input.value);
            output("send: " + input.value);
            input.value = "";
            input.focus();
          }
          
          function onCloseClick() {
            ws.close();
          }
          
          function output(str) {
            var log = document.getElementById("log");
            var escaped = str.replace(/&/, "&amp;").replace(/</, "&lt;").
              replace(/>/, "&gt;").replace(/"/, "&quot;"); // "
            log.innerHTML = escaped + "<br>" + log.innerHTML;
          }
      
        </script>
      </head>
      <body onload="init();">
        <form onsubmit="onSubmit(); return false;">
          <input type="text" id="input">
          <input type="submit" value="Send">
          <button onclick="onCloseClick(); return false;">close</button>
        </form>
        <div id="log"></div>
      </body>
      </html>
      
      1 Reply Last reply Reply Quote 0
      • S Offline
        sakis
        last edited by

        Hi,

        The best place for reporting potential bugs is https://github.com/pycom/pycom-micropython/issues. Can you please file an issue there?

        Thank you

        M 1 Reply Last reply Reply Quote 0
        • M Offline
          matamune @sakis
          last edited by matamune

          @sakis said in Thread WebSocketServer:

          Hi,

          The best place for reporting potential bugs is https://github.com/pycom/pycom-micropython/issues. Can you please file an issue there?

          Thank you

          Hi,
          I have the same issue with a thread with an infinite loop (to display digit on a 7 segments).

          Could it be related with the GC bug? (https://github.com/pycom/pycom-micropython/issues/39)

          S 1 Reply Last reply Reply Quote 0
          • S Offline
            sakis @matamune
            last edited by

            @matamune That's very likely. The best you can do is file a new ticket or if your are sure that it is the same issue add a comment on GitHub.

            1 Reply Last reply Reply Quote 0
            • J Offline
              jobbyworld
              last edited by

              Hello, i fllied a ticked :
              https://github.com/pycom/pycom-micropython/issues/47

              Testing with firmware 0.9.7 don't fix.
              I don't use garbage collector, and my code use only one thread.
              The error only occur after client connected in the message listen loop, and if i use the console.
              But server still running and working after error.
              I suspect interference with console or my own network because error occur only every 30 or 40 seconds

              Hope that it will be fixed by next Release ;-)
              Cheers

              1 Reply Last reply Reply Quote 0

              Hello! It looks like you're interested in this conversation, but you don't have an account yet.

              Getting fed up of having to scroll through the same posts each visit? When you register for an account, you'll always come back to exactly where you were before, and choose to be notified of new replies (either via email, or push notification). You'll also be able to save bookmarks and upvote posts to show your appreciation to other community members.

              With your input, this post could be even better 💗

              Register Login
              • 1 / 1
              • First post
                Last post

              Pycom on Twitter

              Pycom