Git Product home page Git Product logo

websocket-for-python's Introduction

WebSocket for Python (ws4py)

Gitter Build Status PyPI

Python library providing an implementation of the WebSocket protocol defined in RFC 6455.

Read the documentation for more information.

You can also join the ws4py mailing-list to discuss the library.

Installation

pip install ws4py

websocket-for-python's People

Contributors

auvipy avatar awelkie avatar bozzzzo avatar chadselph avatar eliandrewc avatar eternityforest avatar husio avatar jmichiel avatar jodal avatar jon-betts avatar klattimer avatar lawouach avatar methane avatar msabramo avatar noam-graetz avatar patrickod avatar progrium avatar protoss-player avatar rakiru avatar ralhei avatar raven38 avatar rdbhost avatar richo avatar schiermike avatar seanny123 avatar seraphli avatar steowens avatar tito avatar who8mylunch avatar yrttyr avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

websocket-for-python's Issues

wsgi.input _sock not working

I am having followin issue:

File "/usr/local/lib/python2.6/dist-packages/ws4py/server/wsgi/middleware.py", line 117, in call
environ.get('wsgi.input')._sock),
AttributeError: 'Input' object has no attribute '_sock'

I search Input class of pywsgi getevent and did not found _sock function.

chrome 16.0.912.41 beta return code 400

os: mac osx 10.6.2
chrome: 16.0.912.41 beta
ws4py: master

issue:

when use test with echo client , chrome console report server return 400 status code.

client test code:

<script type="text/javascript"> window.onload = function() { var ws_uri = "ws://localhost:9000"; if ("WebSocket" in window) { webSocket = new WebSocket(ws_uri); } else { // Firefox 7/8 currently prefixes the WebSocket object webSocket = new MozWebSocket(ws_uri); } webSocket.onmessage = function(e) { console.log("Got echo: " + e.data); } } </script>

Autobahn WebSockets Echo Test

Send Hello

Using ws4py with standard SocketServer/BaseRequestHandler

Is it possibly/easy to use ws4py with the Python standard modules SocketServer/BaseRequestHandler? If we are able to create such an example and/or server submodule, are there any interest in including that in the ws4py project?

A simpler gevent server example?

I'm trying to write a gunicorn worker class for the gevent-server (along the lines of the one offered by the gevent-websocket library. I find the flow of the gevent-server example difficult to follow.

For instance, what is the purpose of this line https://github.com/Lawouach/WebSocket-for-Python/blob/master/example/echo_gevent_server.py#L47 when the handler_class has already been set to UpgradableWSGIHandler?

Also, what is the difference between UpgradableWSGIHandler and WebSocketUpgradeMiddleware.

infinite loop in threadedclient.py when server closes websocket

I am using geventclient.py which subclasses WebSocketClient in threadedclient.py. The client connects and waits for a message. If the server sends a message and immediately closes the websocket, the client goes into an infinite loop. It happens in threadedclient.py in the _receive() method. Basically, there is a socket recv() command which returns "" indicating that the server has closed. But the _receive() method does not close, and calls socket recv() again. Here is the first part of the function with my patch, which fixes the problem in my limited tests.

def _receive(self):
    next_size = 2
    try:
        self.sock.setblocking(1)
        while self.running:
            if self.__buffer:
                bytes, self.__buffer = self.__buffer[:next_size], self.__buffer[next_size:]
            else:
                bytes = self.read_from_connection(next_size)

            ######### patch start
            if bytes is None or len(bytes) == 0:
                self.server_terminated = True
                self.running = False
                break
            ######### patch end

            with self._lock:
                s = self.stream
                next_size = s.parser.send(bytes)

Server not handling "Upgrade" header case-insensitively, as it should

According to the standard draft 10 that the README says this server conforms to, the Upgrade header should be handled case-insensitively. Currently it is handled case-sensitively.

middleware.py:

def __call__(self, environ, start_response):
    # Initial handshake validation
    try:
        if 'websocket' not in environ.get('upgrade.protocol', ''):
            raise HandshakeError("Upgrade protocol is not websocket")

Exception when running with gevent 1.0

When running geventserver with gevent 1.0, exception occurs

Traceback (most recent call last):
File "build/bdist.macosx-10.7-intel/egg/gevent/pywsgi.py", line 449, in handle_one_response
self.run_application()
File "ws4py/server/geventserver.py", line 64, in run_application
self.result = self.application(self.environ, start_response_for_upgrade)
File "ws4py/server/wsgi/middleware.py", line 127, in call
start_response("101 Web Socket Hybi Handshake", headers)
File "ws4py/server/geventserver.py", line 54, in start_response_for_upgrade
self.wfile.writelines(towrite)
AttributeError: 'UpgradableWSGIHandler' object has no attribute 'wfile'

gevent.pywsgi.WSGIHandler no longer uses attribute wfile.
Here is my fix:

geventserver.py, line 54

self.wfile.writelines(towrite)

self.response_length += sum(len(x) for x in towrite)

self.headers_sent = True # otherwise, write() will send its own headers
for data in towrite:
write(data)

Bad code for binary send in client/__init__.py ??

Something doesn't look right at the end of client/init.py. Is the following correct? Thanks.

diff --git a/ws4py/client/__init__.py b/ws4py/client/__init__.py
index fd6a155..61ed2a3 100644
--- a/ws4py/client/__init__.py
+++ b/ws4py/client/__init__.py
@@ -137,10 +137,10 @@ class WebSocketBaseClient(object):
                 if not binary:
                     self.write_to_connection(self.stream.text_message(bytes).fragment(first=first, mask=True))
                 else:
-                    self.write_to_connection(self.stream.binary_message(payload).fragment(first=first, mask=True))
+                    self.write_to_connection(self.stream.binary_message(bytes).fragment(first=first, mask=True))
                 bytes = chunk
                 first = False
             if not binary:
                 self.write_to_connection(self.stream.text_message(bytes).fragment(last=True, mask=True))
             else:
-                self.write_to_connection(self.stream.text_message(bytes).fragment(last=True, mask=True))
+                self.write_to_connection(self.stream.binary_message(bytes).fragment(last=True, mask=True))

remove implicit gevent monkey patching in the gevent client

By implicitly calling monkey.patch_all() in the gevent client, you are making the assumption that the code that uses your library wants the stdlib to be completely patched.

This may lead to locking issues & conflicts depending on the execution environment.

I would suggest removing that call and let the library users decide what they want to do

ws4py.client.threadedclient is not compatible with ws4py.server.cherrypyserver

We've been unable to run a CherryPy websocket server and then connect to it with the ws4py.client.threadedclient library without seeing unexpected connection closes and exceptions. This even happens with the example CherryPy echo client / server code. To reproduce, you can enter the following commands in a console:

python2.7 -m virtualenv --no-site-packages env
source env/bin/activate
pip install http://www.defuze.org/oss/ws4py/ws4py-0.2.1.tar.gz
pip install http://download.cherrypy.org/cherrypy/3.2.2/CherryPy-3.2.2.tar.gz
git clone https://github.com/Lawouach/WebSocket-for-Python.git
python WebSocket-for-Python/example/echo_cherrypy_server.py

and then in another console in the same directory type:

source env/bin/activate
python WebSocket-for-Python/example/echo_client.py

and you'll see the following output

0
25
50
75
100
125
150
175
=> 708 ####################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################
=> 0 
=> 25 *************************
=> 50 **************************************************
=> 75 ***************************************************************************
=> 100 ****************************************************************************************************
=> 125 *****************************************************************************************************************************
=> 150 ******************************************************************************************************************************************************
=> 175 *******************************************************************************************************************************************************************************
Closed down 1006 Going away
Exception in thread WebSocketClient:
Traceback (most recent call last):
  File "/usr/local/lib/python2.7/threading.py", line 552, in __bootstrap_inner
    self.run()
  File "/usr/local/lib/python2.7/threading.py", line 505, in run
    self.__target(*self.__args, **self.__kwargs)
  File "/home/eli/temp/ws4py/env/lib/python2.7/site-packages/ws4py/websocket.py", line 230, in run
    if not process(bytes):
  File "/home/eli/temp/ws4py/env/lib/python2.7/site-packages/ws4py/websocket.py", line 265, in process
    self.reading_buffer_size = s.parser.send(bytes) or DEFAULT_READING_SIZE
  File "/home/eli/temp/ws4py/env/lib/python2.7/site-packages/ws4py/streaming.py", line 258, in receiver
    is_valid, end_on_code_point, _, _ = utf8validator.validate(reason)
  File "/home/eli/temp/ws4py/env/lib/python2.7/site-packages/ws4py/utf8validator.py", line 108, in validate
    self.state = Utf8Validator.UTF8VALIDATOR_DFA[256 + (self.state << 4) + Utf8Validator.UTF8VALIDATOR_DFA[ba[i]]]
TypeError: list indices must be integers, not str

So it looks like the data transfer works for awhile, but then shuts down before all of the data can be sent back and forth. This did not happen in previous versions; we're still using ws4py 0.1.3 for our development because this doesn't seem to happen with that release.

We have reproduced this issue on both Python 2.6 and 2.7, and it occurs on both OSX and Ubuntu. Please let me know if there's anything else I can do to help.

Bug in documentation

sphinx-build -b html -d _build/doctrees . _build/html
Making output directory...
Running Sphinx v1.1.3
loading pickled environment... not yet created
building [html]: targets for 10 source files that are out of date
updating environment: 10 added, 0 changed, 0 removed
reading sources... [ 70%] ws4py
Sphinx error:
'utf8' codec can't decode byte 0xbe in position 146: invalid start byte
make: *** [html] Error 1

Strange traceback with WebSocket.send

I use ws4py with Cherrypy (the plugin and the tool provided).

It works just fine most of the time, but sometimes I have in my log a traceback like that. I didn't remove any line from it, more explanations are given below:

Exception in thread WebSocket client at _..**.**_:56741:
Traceback (most recent call last):
File "/usr/local/lib/python3.3/threading.py", line 639, in _bootstrap_inner
self.run()
File "/usr/local/lib/python3.3/threading.py", line 596, in run
self._target(_self._args, *_self._kwargs)
File "/usr/local/lib/python3.3/site-packages/ws4py-0.2.5-py3.3.egg/ws4py/websocket.py", line 291, in run
if not process(bytes):
File "/usr/local/lib/python3.3/site-packages/ws4py-0.2.5-py3.3.egg/ws4py/websocket.py", line 343, in process
self.received_message(s.message)
File "/home/vlegoff/pa-poc2/scripts/../plugins/websocket/handler.py", line 86, in received_message
function(**args)
File "/home/vlegoff/pa-poc2/scripts/../bundles/chat/websockets/chat.py", line 32, in handle_setpseudo
self.send_to_connected(welcome, self)
File "/home/vlegoff/pa-poc2/scripts/../bundles/chat/websockets/chat.py", line 58, in send_to_connected
ws_handler.send_message(message, escape=escape)
File "/home/vlegoff/pa-poc2/scripts/../bundles/chat/websockets/chat.py", line 69, in send_message
self.send_JSON("message", message=message)
File "/home/vlegoff/pa-poc2/scripts/../plugins/websocket/handler.py", line 110, in send_JSON
self.send_text(text)
File "/home/vlegoff/pa-poc2/scripts/../plugins/websocket/handler.py", line 101, in send_text
self.send(msg)
File "/usr/local/lib/python3.3/site-packages/ws4py-0.2.5-py3.3.egg/ws4py/websocket.py", line 219, in send
message_sender = self.stream.binary_message if binary else self.stream.text_message
AttributeError: 'NoneType' object has no attribute 'text_message'

The almost last lines are part of my application: I have a WebSocketHandler (the Chat class inherited from WebSocket defined in ws4py). The goal is to send a message to one of the connected client and it finally crashes on the WebSocket.send method.

Do you know why this happens and how to fix it? Is it a ws4py bug or a wrong usage in my application?

TornadoWebSocketClient doesn't support SSL

When creating WebSockets with a WSS:// URL the TornadoWebSocketClient class fails to connect. The following is the code snippet that I'm using to test the functionality.

from ws4py.client.tornadoclient import TornadoWebSocketClient
import tornado.ioloop
c = TornadoWebSocketClient("wss://127.0.0.1:8888/")
c.connect()
tornado.ioloop.IOLoop.instance().start()

The server is a simple demo Tornado Server with SSL enabled. The error on the server side is the following

WARNING:root:SSL Error on 8: [Errno 1] _ssl.c:490: error:1407609C:SSL routines:SSL23_GET_CLIENT_HELLO:http request

The error on the client side is the following

WARNING:root:Read error on 3: [Errno 104] Connection reset by peer
ERROR:root:Uncaught exception, closing connection.
Traceback (most recent call last):
  File "/usr/local/lib/python2.6/dist-packages/tornado/iostream.py", line 304, in wrapper
    callback(*args)
  File "/usr/local/lib/python2.6/dist-packages/ws4py-0.2.0-py2.6.egg/ws4py/client/tornadoclient.py", line 34, in __handshake_sent
    self.io.read_until("\r\n\r\n", self.__handshake_completed)
  File "/usr/local/lib/python2.6/dist-packages/tornado/iostream.py", line 160, in read_until
    self._check_closed()
  File "/usr/local/lib/python2.6/dist-packages/tornado/iostream.py", line 535, in _check_closed
    raise IOError("Stream is closed")
IOError: Stream is closed
ERROR:root:Exception in callback <tornado.stack_context._StackContextWrapper object at 0x99e89dc>
Traceback (most recent call last):
  File "/usr/local/lib/python2.6/dist-packages/tornado/ioloop.py", line 399, in _run_callback
    callback()
  File "/usr/local/lib/python2.6/dist-packages/tornado/iostream.py", line 304, in wrapper
    callback(*args)
  File "/usr/local/lib/python2.6/dist-packages/ws4py-0.2.0-py2.6.egg/ws4py/client/tornadoclient.py", line 34, in __handshake_sent
    self.io.read_until("\r\n\r\n", self.__handshake_completed)
  File "/usr/local/lib/python2.6/dist-packages/tornado/iostream.py", line 160, in read_until
    self._check_closed()
  File "/usr/local/lib/python2.6/dist-packages/tornado/iostream.py", line 535, in _check_closed
    raise IOError("Stream is closed")
IOError: Stream is closed
^CTraceback (most recent call last):
  File "test.py", line 5, in <module>
    tornado.ioloop.IOLoop.instance().start()
  File "/usr/local/lib/python2.6/dist-packages/tornado/ioloop.py", line 282, in start
    event_pairs = self._impl.poll(poll_timeout)
KeyboardInterrupt

The problem is limited solely to the TornadoWebSocketClient class. Both of the other clients work with the server and SSL enabled. I think the problem is due to not using a tornado.iostream.SSLIOStream object in place of a tornado.iostream.IOStream object. I'll try and confirm my suspicions and post a fix if I can.

tools.websocket.version should allow more than one version

The latest Firefox and the latest Google Chrome set the value of the "Sec-WebSocket-Version" header to 8 and 13, respectively. I can set the version that CherryPy expects with the "tools.websocket.version" config option, but this setting is used in a basic equality check (https://github.com/Lawouach/WebSocket-for-Python/blob/master/ws4py/server/cherrypyserver.py#L133). So currently I can deploy a site which is compatible with the latest Firefox or the latest Chrome, but not both.

I propose that "tools.websocket.version" accept either a number or a range. So I could say either

tools.websocket.version = 8

or

tools.websocket.version = 8-13

I will submit a patch via a Github pull request sometime this week which adds this functionality.

Gradually drop support for Python <2.7 and <3.3.2

Following Armin's comment, I'm tempted to drop anything but 2.7 and 3.3.2. Mostly, it would simplify tremendously the string/bytes handling across the board as we could use unicode/bytes litterals. I'd be surprised if it wouldn't improve performances a little as well.

It would happen after 0.3.0 release, so that people still using other versions can benefit from the latest fixes.

Port to Python 3

Find the best approach to port to py3k, probably at a compat module like CherryPy uses.

Problem creating a websocket

I'm trying to execute any example code and everytime the socket is created, python throws an exception like this:

127.0.0.1 - - [11/Mar/2012:11:10:45] "GET /js/jquery-1.6.2.min.js HTTP/1.1" 304 - "http://localhost:9000/" "Mozilla/5.0 (X11; Linux i686) AppleWebKit/535.11 (KHTML, like Gecko) Ubuntu/11.10 Chromium/17.0.963.78 Chrome/17.0.963.78 Safari/535.11"
[11/Mar/2012:11:10:45]  Handler created: <__main__.ChatWebSocketHandler object at 0x94d402c>
127.0.0.1 - - [11/Mar/2012:11:10:45] "GET /ws HTTP/1.1" 101 - "" ""
[11/Mar/2012:11:10:45]  Managing WebSocket connection from 127.0.0.1:54256
[11/Mar/2012:11:10:46]  Traceback (most recent call last):
  File "/usr/local/lib/python2.7/dist-packages/ws4py/server/cherrypyserver.py", line 339, in broadcast
    ws_handler.send(message, message.is_binary)
  File "/usr/local/lib/python2.7/dist-packages/ws4py/websocket.py", line 172, in send
    self.sender(payload.single(mask=self.stream.always_mask))
  File "/usr/lib/python2.7/socket.py", line 224, in meth
    return getattr(self._sock,name)(*args)
  File "/usr/lib/python2.7/socket.py", line 170, in _dummy
    raise error(EBADF, 'Bad file descriptor')
error: [Errno 9] Bad file descriptor

I'm not really sure what I'm doing wrong, but using another ws4py version doesn't seem to solve it...

Steps to reproduce(?):

  1. git clone https://github.com/Lawouach/WebSocket-for-Python.git
  2. cd WebSocket-for-Python/
  3. sudo python setup.py install
  4. python example/echo_cherrypy_server.py
  5. Open chromium. Go to address: localhost:9000

Result:

  • Chat site appears. There is one message in the chat window: Connection closed by server: 1006 ""
  • Stack trace that appears in the server console above.

WSGI variables, cookies and transparent websocket authentication.

The websocket appears to have some wsgi variables set. Is it correct that websocket.path == environ.PATH_INFO?

Is that the only wsgi environ set on the websocket? Checking the websocket for CONTENT_TYPE, HTTP_USER_AGENT, variables set on wsgi environment, shows they aren't set on the websocket.

Strangely enough, HTTP_COOKIE isn't set on the wsgi environment available on the wsgi app handler if the client is a Javascript websocket client on the Chrome browser. I haven't tested a python client (or other browser clients) to check whether Chrome is transmitting host cookies on the websocket connection.

I'm attempting to use client cookies to authenticate the websocket connection instead of performing additional explicit websocket authentication on the first websocket message.

Any thoughts?

Please store the close code and reason in WebSocketBaseClient

When the websocket closes, there is a code and a reason. I can subclass it and override closed() to get these. But I cannot get them if I am handed a stock websocket object, for example when I use WSGI server (with gevent). Therefore, could you please store the code and reason in the websocket? For example,

ws4py/client/init.py line 106

def close(self, reason='', code=1000):
    if not self.client_terminated:
        self.client_terminated = True
        self.close_code = code  ### added ###
        self.close_reason = reason ### added ###
        self.write_to_connection(self.stream.close(code=code, reason=reason).single(mask=True))

TypeError: list indices must be integers, not str

I receive this error:

Traceback (most recent call last):
  File "venv/lib/python2.6/site-packages/ws4py/client/threadedclient.py", line 93, in _receive
    next_size = s.parser.send(bytes)
  File "venv/lib/python2.6/site-packages/ws4py/streaming.py", line 181, in receiver
    is_valid, _, _, _ = utf8validator.validate(bytes)
  File "venv/lib/python2.6/site-packages/ws4py/utf8validator.py", line 108, in validate
    self.state = Utf8Validator.UTF8VALIDATOR_DFA[256 + (self.state << 4) + Utf8Validator.UTF8VALIDATOR_DFA[ba[i]]]
TypeError: list indices must be integers, not str

IPv6 sockets not supported

When a WebSocket is created using an underlying IPv6 socket, its local_address (and, I assume, the peer address) returns a 4-tuple instead of a 2-tuple.

This means that automatic unpacking of the address into hostname, port throws a ValueError.

Minimal example (using the cherrypy tools)

import cherrypy
from ws4py.server.cherrypyserver import WebSocketPlugin, WebSocketTool
from ws4py.websocket import EchoWebSocket

cherrypy.config.update({'server.socket_port': 9000})
cherrypy.config.update({'server.socket_host': "::1"})
WebSocketPlugin(cherrypy.engine).subscribe()
cherrypy.tools.websocket = WebSocketTool()

class Root(object):
    @cherrypy.expose
    def index(self):
        return """<script type="text/javascript">
      var sock = new WebSocket("ws://localhost:9000/ws");</script>"""

    @cherrypy.expose
    def ws(self):
      pass

cherrypy.quickstart(Root(), '/', config={'/ws': {'tools.websocket.on': True,
                                                 'tools.websocket.handler_cls': EchoWebSocket}})

This throws a ValueError when navigating to localhost:9000

The obvious workaround is not using IPv6 addresses in the server deployment.

A fix would be to have WebSocket.local_address and WebSocket.peer_address return the first two elements of the underlying socket's name.

In client/__init__.py: remaining 'body' bytes ignored

client/init.py has:

self.__buffer = body

It looks like self.__buffer is never used, which means that if any bytes (e.g., the first data packet) are received along with the headers, those bytes will be ignored and the connection will probably get into a bad state.

Adding this after handshake_ok() fixes things in this case:

if body != '':
process(body)

Does that seem like a reasonable fix?

wss server support

i have realized wss server using ws4py and cherrypy for python 2.6 but it looks very strange
I understand ssl.SSLSocket send\recv works only with string not bytearray and
for sending string 'abcd' it must looks like '\x82\x06abcd\r'
it''ll be cool to have ability to work with bytearray by wss

ThreadedHandler still referenced

It is imported in:

  • ws4py/websocket.py
  • ws4py/server/cherrypyserver.py
  • test/test_cherrypy.py
  • example/droid_sensor_cherrypy_server.py

Support `ws+unix` scheme

I know, it’s not part of the official spec, but you can run websockets over local unix sockets just fine.
The node.js ws module supports servers and clients that bind to local unix sockets. I have a node.js server which acts as WS server and I want to consume it via python.

memory leak

The server has a memory leak. I found it because my server ran out of memory after several thousand clients connected and disconnected. I verified the leak using Python objgraph pypi.python.org/pypi/objgraph . It appears that for every websocket connection, two generators, one Stream, and one Frame are leaked. Even after the connection is closed, these objects remain in memory. Even after garbage collection. To verify it, add the following two lines to the sample echo server.

    for x in ['generator', 'Stream', 'Frame', 'TextMessage']:
        print x, len(objgraph.by_type(x))

Now connect and disconnect several clients. You will see the number of instances of these objects climb, even after all clients are disconnected, even after garbage collection.

I use geventserver. I have not tried with the other servers. But there is no leakage of Greenlets, so I suspect the issue is not related to gevent.

ImportError: No module named gevent

Happily installed ws4py and all the other goodies and was thrilled to launch 'echo_cherrypy_server.py' and see it working flawlessly in Chrome. However, seems other python programs in examples directory are not working at all. For instance...

$ python autobahn_test_servers.py

python echo_client.py
Traceback (most recent call last):
File "echo_client.py", line 27, in
ws.connect()
File "/Library/Python/2.7/site-packages/ws4py/client/init.py", line 58, in connect
self.process_response_line(response_line)
File "/Library/Python/2.7/site-packages/ws4py/client/init.py", line 102, in process_response_line
raise HandshakeError("Invalid response status: %s %s" % (code, status))
ws4py.exc.HandshakeError: Invalid response status: 404 Not Found

I'm running OSX Lion 10.7.3, Python 2.7.1 (r271:86832, Jun 16 2011, 16:59:05)
[GCC 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2335.15.00)] on darwin

Inconsistent tabs/spaces

The file ws4py/server/cherrypyserver.py contains a few tabs that should be replaced by 8 spaces each.

Socket not properly closed in Win7

Working with python3.2, a closed socket is not properly removed from the 'pool' (?) of sockets to send a message through.

When the browser is closing its connection the server receives it, processes it (cleans all up, making the WebSocket members all None types), but somehow it stays there. Resulting in a persisting attribute error :

'NoneType' object has no attribute 'text_message'

urlsplit in Python 2.6.1 and earlier doesn't parse ws or wss properly.

>>> urlsplit('ws://localhost:8080/some-path')
SplitResult(scheme='ws', netloc='', path='//localhost:8080/some-path', query='', fragment='')

This results in 'host' being None, and an obtuse 'Connection Refused' message passed to close(), but without enough information to debug.

I see that 'websocket-client' has it's own _parse_url method that works around this bug:

https://github.com/liris/websocket-client/blob/master/websocket.py#L105

I'll try and work up a patch, if a solution like the above is reasonable?

Thanks

Threaded WebSocket client always exits randomly

I tried to implement a simple WebSocket client for a CherryPy server which should work like the droid_sensor.py and its server under "example", but if I try to run the client it always stops randomly in the send loop and exits with a random WebSocket error code (one of 1002, 1006 and 1007).

This is the server log from the CherryPy server:

127.0.0.1 - - [18/Feb/2013:02:49:54] "GET /ws HTTP/1.1" 101 - "" ""
[18/Feb/2013:02:49:54]  Managing WebSocket connection from 127.0.0.1:55280
[18/Feb/2013:02:49:54]  Managing WebSocket connection from 127.0.0.1:55280
Exception in thread WebSocket client at 127.0.0.1:55280:
Traceback (most recent call last):
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py", line 552, in __bootstrap_inner
    self.run()
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py", line 505, in run
    self.__target(*self.__args, **self.__kwargs)
  File "/Users/martin/Desktop/test/ENV/lib/python2.7/site-packages/ws4py/websocket.py", line 246, in run
    self._cleanup()
  File "/Users/martin/Desktop/test/ENV/lib/python2.7/site-packages/ws4py/websocket.py", line 197, in _cleanup
    self.stream._cleanup()
AttributeError: 'NoneType' object has no attribute '_cleanup'

[18/Feb/2013:02:49:55]  Removing WebSocket connection 127.0.0.1:55280
[18/Feb/2013:02:49:55]  Removing WebSocket connection 127.0.0.1:55280

This is my client (very similar to example/droid_sensor.py):
https://gist.github.com/muellermartin/4974648

and this is the server:
https://gist.github.com/muellermartin/4974657

P.S.: The host in line https://github.com/Lawouach/WebSocket-for-Python/blob/master/example/droid_sensor.py#L98 seems to be wrong (script crashes with ValueError: Invalid scheme: http) - shouldn't this be "ws://127.0.0.1:9000/ws"?

ws4py.server.wsgiutils.py got some error in python 3.3

Test Code

I tring to use bottlepy with ws4py in python 3.3 like this:

# ws4py -> wsapp
from ws4py.server.wsgiutils import WebSocketWSGIApplication
from ws4py.websocket import EchoWebSocket
wsapp = WebSocketWSGIApplication(handler_cls = EchoWebSocket)

# Bottlepy -> app
from bottle import Bottle, run
app = Bottle(catchall = True)

# mount wsapp on app (use bottle API)
app.mount('/ws', wsapp) # mount websocket at "/127.0.0.1:8080/ws"

run(app = app, host = '127.0.0.1', port = '8080',
    debug = True, quiet = False)

And I test WebSocket Function with WebSocket Echo Page (using ws://127.0.0.1:8080/ws as location), browser is firefox 20.0 .

Error

But I got some error:

Line 146

    ('Sec-WebSocket-Accept', base64.b64encode(sha1(key + WS_KEY).digest())),
TypeError: Can't convert 'bytes' object to str implicitly

I try to use bytes(key, 'utf8') to workaround (not sure it really ok or not...), but another error appear...

Line 155

    self.make_websocket(environ['ws4py.socket'],
KeyError: 'ws4py.socket'

Please give me a hand... thanks!

platform info

exception not catch in websocket.py always

File "build/bdist.linux-i686/egg/ws4py/websocket.py", line 232, in run
bytes = sock.recv(self.reading_buffer_size)
error: [Errno 110] Connection timed out


i think can except this exception then call closed func like this:

    try:
        self.opened()
        sock = self.sock
        fileno = sock.fileno()
        process = self.process

        while not self.terminated:
            bytes = sock.recv(self.reading_buffer_size)
            if not process(bytes):
                break
    except:
        self.closed(110, "Connection timed out")

    finally:
        self.client_terminated = self.server_terminated = True

        try:
            if not s.closing:
                self.closed(1006, "Going away")
            else:
                self.closed(s.closing.code, s.closing.reason)
        finally:
            s = sock = fileno = process = None
            self.close_connection()
            self._cleanup()

HandshakeError: WebSocket version required

Apple devices do not work with ws4py, they produce HandshakeError: WebSocket version required error. They only work with allow_draft76 with Tornado, but I would like to use cherrypy. Is this a limitation in ws4py or cherrypy? Is there a reason not to enable these devices? If no, is there a simple solution or a workaround to use them?

KeyboardInterrupt ignored in WebSocketClient

I'm using ws4py to build a simple command-line WS client. However, once it gets going, there's no way to bring it down without killing it. I see that WebSocketClient is using the threading package; how can I get it to close the connection on KeyboardInterrupt (or something similar)?

The code (set WEBSOCKET_SERVER_URL to a real WS server):

from ws4py.client.threadedclient import WebSocketClient

WEBSOCKET_SERVER_URL = "INSERT_VALID_URL_HERE"

class CantInterruptClient(WebSocketClient):
    def opened(self):
        print "Opened."

    def closed(self, code):
        print "Closed."

try:
    print "Creating client..."
    cant_interrupt_client = CantInterruptClient(WEBSOCKET_SERVER_URL)
    cant_interrupt_client.connect()
except KeyboardInterrupt:
    print "Attempting to quit..."
    cant_interrupt_client.close()

Typical command line output:

$ python ws4py-interrupt.py
Creating client...
Opened.
^C^C^C^C^C^C^C^C

How to select sub-protocol? And related sub-protocol spec compliance issue

How do I specify what sub-protocols my application supports? I see that the WebSocketTool upgrade method takes a protocols named parameter but how do I specify that list from my application.

Also, I've noticed a spec compliance issue in the upgrade method (e.g. server/cherrypyserver.py about line 158):

if s in protocols:
    ws_protocols.append(s)

and then later:

if ws_protocols:
    response.headers['Sec-WebSocket-Protocol'] = ', '.join(ws_protocols)

While a client is allowed to specify multiple comma separated sub-protocols in the handshake request, the handshake response must only contain one of those items that the server has selected. See the /subprotocol/ description in the server handshake section: http://tools.ietf.org/html/rfc6455#section-4.2.2

echo_cherrypy_server with Python 3.2 fails on client connection

When launching the 'echo_cherrypy_server.py' example, the CherryPy server starts, but the client connection fails with a TypeError.

To reproduce:

  1. Launch the 'echo_cherrypy_server.py' example with Python 3.2 [1]
  2. Open a compatible browser (Mozilla Firefox 16 in my case) and go to the URL: http://localhost:9000
  3. On the server-side (Python console), the following error occurs:

[31/Oct/2012:10:40:14] HTTP
Request Headers:
PRAGMA: no-cache
UPGRADE: websocket
HOST: 127.0.0.1:9000
ORIGIN: http://localhost:9000
CONNECTION: keep-alive, Upgrade
CACHE-CONTROL: no-cache
SEC-WEBSOCKET-VERSION: 13
ACCEPT: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8
USER-AGENT: Mozilla/5.0 (Windows NT 6.1; rv:16.0) Gecko/20100101 Firefox/16.0
ACCEPT-LANGUAGE: fr,fr-fr;q=0.8,en-us;q=0.5,en;q=0.3
SEC-WEBSOCKET-KEY: 6mxn50NE+8xKZ15w2/NQRw==
Remote-Addr: 127.0.0.1
ACCEPT-ENCODING: gzip, deflate
[31/Oct/2012:10:40:14] HTTP Traceback (most recent call last):
File "C:\python32\lib\site-packages\cherrypy-3.2.2-py3.2.egg\cherrypy_cprequest.py", line 647, in respond
self.hooks.run('before_request_body')
File "C:\python32\lib\site-packages\cherrypy-3.2.2-py3.2.egg\cherrypy_cprequest.py", line 112, in run
raise exc
File "C:\python32\lib\site-packages\cherrypy-3.2.2-py3.2.egg\cherrypy_cprequest.py", line 102, in run
hook()
File "C:\python32\lib\site-packages\cherrypy-3.2.2-py3.2.egg\cherrypy_cprequest.py", line 62, in call
return self.callback(**self.kwargs)
File "C:\python32\lib\site-packages\ws4py-0.2.3-py3.2.egg\ws4py\server\cherrypyserver.py", line 149, in upgrade
ws_key = base64.b64decode(key)
File "C:\python32\lib\base64.py", line 83, in b64decode
raise TypeError("expected bytes, not %s" % s.class.name)
TypeError: expected bytes, not str

127.0.0.1 - - [31/Oct/2012:10:40:14] "GET /ws HTTP/1.1" 500 1686 "" "Mozilla/5.0 (Windows NT 6.1; rv:16.0) Gecko/20100101 Firefox/16.0"

[1] Windows 7, Python 3.2.3, CherryPy 3.2.2.

Typos following recent code changes...

diff --git a/example/echo_client.py b/example/echo_client.py
index 94b1f04..9b6698e 100644
--- a/example/echo_client.py
+++ b/example/echo_client.py
@@ -13,7 +13,7 @@ class EchoClient(WebSocketClient):
             print i
             self.send("*" * i)

-    def closed(self, code, reason):
+    def closed(self, code, reason=None):
         print "Closed down", code, reason

     def received_message(self, m):
diff --git a/ws4py/exc.py b/ws4py/exc.py
index 5a87f36..5a22ee2 100644
--- a/ws4py/exc.py
+++ b/ws4py/exc.py
@@ -1,7 +1,7 @@
 # -*- coding: utf-8 -*-

 __all__ = ['WebSocketException', 'FrameTooLargeException', 'ProtocolException',
-           'FUnsupportedFrameTypeException', 'TextFrameEncodingException',
+           'UnsupportedFrameTypeException', 'TextFrameEncodingException',
            'StreamClosed', 'HandshakeError', 'InvalidBytesError']

 class WebSocketException(Exception): pass
diff --git a/ws4py/websocket.py b/ws4py/websocket.py
index bbff576..cf78b8a 100644
--- a/ws4py/websocket.py
+++ b/ws4py/websocket.py
@@ -135,7 +135,7 @@ class WebSocket(object):
             bytes = payload.next()
             first = True
             for chunk in payload:
-                write(message_sender(bytes).fragment(first=first))
+                self.sender(message_sender(bytes).fragment(first=first))
                 bytes = chunk
                 first = False

Sending Messages To Individual Clients

Is there a way to send messages to individual clients using client IDs? It would be awesome if you could include that in the chat example or let me know if you plan to implement it. This would be useful, for example, in a chat server that supports private messages.

Lack of trailing slash creates invalid GET call

If you use a line like ws = EchoClient('wss://myserver.org:443') you get an invalid GET request:

0000 47 45 54 20 20 48 54 54 50 2f 31 2e 31 0d 0a 48 GET HTTP/1.1..H

Note the lack of a / there between the GET and HTTP/1.1.

Using ws = EchoClient('wss://myserver.org:443/') works as expected.

Lack of a trailing slash when requesting a site's root really ought to be handled properly.

test_cherrypy.py fails with py3

This appears to have been in place for some time. I only picked it up in the process of preparing a version bump, to 0.2.4, requested by another, gentoo

platform linux2 -- Python 3.2.3 -- pytest-2.2.4
collected 22 items

test/test_cherrypy.py F
test/test_frame.py ............
test/test_stream.py .........

=================================== FAILURES ===================================
___________________________ CherryPyTest.test_plugin ___________________________

self = <test.test_cherrypy.CherryPyTest testMethod=test_plugin>

def test_plugin(self):
    self.assertEquals(len(cherrypy.engine.websocket.pool), 0)

    s = FakeSocket()
    h = EchoWebSocket(s, [], [])
    cherrypy.engine.publish('handle-websocket', h, ('127.0.0.1', 0))
    self.assertEquals(len(cherrypy.engine.websocket.pool), 1)
  k = cherrypy.engine.websocket.pool.keys()[0]

E TypeError: 'dict_keys' object does not support indexing

test/test_cherrypy.py:68: TypeError
===================== 1 failed, 21 passed in 0.67 seconds ======================

  • ERROR: dev-python/ws4py-0.2.3 failed (test phase):

You can tell me if this is coming from ws4py here of from cherrypy itself. Holds true for
cherrypy-3.2.0 - 3.2.2

ws4py shouldn't send a masked message to the client

The latest version of chrome has started to fail for me with a message about the server sending a masked message. I found this commit: 19cfdb1 which seems seems to be addressing the issue.

If I install version 0.1.3 my websockets communication works again.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.