Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
W
wspy
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Taddeüs Kroes
wspy
Commits
5034eae4
Commit
5034eae4
authored
Aug 19, 2013
by
Taddeüs Kroes
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Documentation
parent
b4bd4350
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
162 additions
and
17 deletions
+162
-17
README.md
README.md
+128
-6
connection.py
connection.py
+26
-4
server.py
server.py
+8
-7
No files found.
README.md
View file @
5034eae4
**twspy**
is a standalone implementation of web sockets for Python, defined by
About
[
RFC 6455
](
http://tools.ietf.org/html/rfc6455
)
.
=====
-
The
`websocket`
class upgrades a regular socket to a web socket. A websocket
*twspy*
is a standalone implementation of web sockets for Python, defined by
instance is a single end point of a connection. A
`websocket`
instance sends
[
RFC 6455
](
http://tools.ietf.org/html/rfc6455
)
. The incentive for creating this
and receives frames (
`Frame`
instances) as opposed to bytes (which are
library is the absence of a layered implementation of web sockets outside the
sent/received in a regular socket).
scope of web servers such as Apache or Nginx.
*twspy*
does not require any
third-party programs or libraries outside Python's standard library. It
provides low-level access to sockets, as well as high-level functionalities to
easily set up a web server. Thus, it is both suited for quick server
programming, as well as for more demanding applications that require low-level
control over each frame being sent/received.
Her is a quick overview of the features in this library:
-
Upgrading regular sockets to web sockets.
-
Building custom frames.
-
Messages, which are higher-level than frames (see "Basic usage").
-
Connections, which hide the handling of control frames and automatically
concatenate fragmented messages to individual payloads.
-
HTTP authentication during handshake.
-
An extendible server implementation.
-
Secure sockets using SSL certificates (for 'wss://...' URL's).
-
The possibility to add extensions to the web socket protocol. An included
implementation is
[
deflate-frame
](
http://tools.ietf.org/html/draft-tyoshino-hybi-websocket-perframe-deflate-06
)
.
Basic usage
===========
-
The
`websocket`
class upgrades a regular socket to a web socket. A
`websocket`
instance is a single end point of a connection. A
`websocket`
instance sends and receives frames (
`Frame`
instances) as opposed to bytes
(which are sent/received in a regular socket).
Server example:
import twspy, socket
sock = twspy.websocket()
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind(('', 8000))
sock.listen()
client = sock.accept()
client.send(twspy.Frame(twspy.OPCODE_TEXT, 'Hello, Client!'))
frame = client.recv()
Client example:
import twspy
sock = twspy.websocket(location='/my/path')
sock.connect(('', 8000))
sock.send(twspy.Frame(twspy.OPCODE_TEXT, 'Hello, Server!'))
-
A
`Connection`
instance represents a connection between two end points, based
-
A
`Connection`
instance represents a connection between two end points, based
on a
`websocket`
instance. A connection handles control frames properly, and
on a
`websocket`
instance. A connection handles control frames properly, and
...
@@ -12,3 +57,80 @@
...
@@ -12,3 +57,80 @@
frames). Messages are automatically converted to frames, and received frames
frames). Messages are automatically converted to frames, and received frames
are converted to messages. Fragmented messages (messages consisting of
are converted to messages. Fragmented messages (messages consisting of
multiple frames) are also supported.
multiple frames) are also supported.
Example of an echo server (sends back what it receives):
import twspy
class EchoConnection(twspy.Connection):
def onopen(self):
print 'Connection opened at %s:%d' % self.sock.getpeername()
def onmessage(self, message):
print 'Received message "%s"' % message.payload
self.send(twspy.TextMessage(message.payload))
def onclose(self, message):
print 'Connection closed'
server = twspy.websocket()
server.bind(('', 8000))
server.listen()
while True:
client, addr = server.accept()
EchoConnection(client).receive_forever()
There are two types of messages:
`TextMessage`
s and
`BinaryMessage`
s. A
`TextMessage`
uses frames with opcode
`OPCODE_TEXT`
, and encodes its payload
using UTF-8 encoding. A
`BinaryMessage`
just sends its payload as raw data.
I recommend using
`TextMessage`
by default, and
`BinaryMessage`
only when
necessary.
**Note:**
For browser clients, you will probably want to use JSON encoding.
This could, for example, be implemented as follows:
import twspy, json
def msg(**data):
return twspy.TextMessage(json.dumps(data))
# create some connection `conn`...
conn.send(msg(foo='Hello, World!'))
-
The built-in
`Server`
implementation is very basic. It starts a new thread
with a
`Connection.receive_forever()`
loop for each client that connects. It
also handles client crashes properly. By default, a
`Server`
instance only
logs every event using Python's
`logging`
module. To create a custom server,
The
`Server`
class should be extended and its event handlers overwritten. The
event handlers are named identically to the
`Connection`
event handlers, but
they also receive an additional
`client`
argument. This argument is a
modified
`Connection`
instance, so you can invoke
`send()`
and
`recv()`
.
For example, the
`EchoConnection`
example above can be rewritten to:
import twspy
class EchoServer(twspy.Server):
def onopen(self, client):
print 'Client %s connected' % client
def onmessage(self, client, message):
print 'Received message "%s"' % message.payload
client.send(twspy.TextMessage(message.payload))
def onclose(self, client):
print 'Client %s disconnected' % client
EchoServer(8000).run()
The server can be stopped by typing CTRL-C in the command line. The
`KeyboardInterrupt`
raised when this happens is caught by the server.
Extensions
==========
TODO
connection.py
View file @
5034eae4
...
@@ -9,12 +9,34 @@ from errors import SocketClosed, PingError
...
@@ -9,12 +9,34 @@ from errors import SocketClosed, PingError
class
Connection
(
object
):
class
Connection
(
object
):
"""
"""
A
Connection uses a websocket
instance to send and receive (optionally
A
`Connection` uses a `websocket`
instance to send and receive (optionally
fragmented) messages, which are
Message
instances. Control frames are
fragmented) messages, which are
`Message`
instances. Control frames are
handled automatically in the way specified by RFC 6455.
handled automatically in the way specified by RFC 6455.
To use the Connection class, it should be extended and the extending class
To use the `Connection` class, it should be extended and the extending
should implement the on*() event handlers.
class should implement the on*() event handlers.
Example of an echo server (sends back what it receives):
>>> import twspy
>>> class EchoConnection(twspy.Connection):
>>> def onopen(self):
>>> print 'Connection opened at %s:%d' % self.sock.getpeername()
>>> def onmessage(self, message):
>>> print 'Received message "%s"' % message.payload
>>> self.send(twspy.TextMessage(message.payload))
>>> def onclose(self, message):
>>> print 'Connection closed'
>>> server = twspy.websocket()
>>> server.bind(('', 8000))
>>> server.listen()
>>> while True:
>>> client, addr = server.accept()
>>> EchoConnection(client).receive_forever()
"""
"""
def
__init__
(
self
,
sock
):
def
__init__
(
self
,
sock
):
"""
"""
...
...
server.py
View file @
5034eae4
...
@@ -18,17 +18,18 @@ class Server(object):
...
@@ -18,17 +18,18 @@ class Server(object):
Example usage:
Example usage:
>>> import twspy
>>> import twspy
>>> class
Game
Server(twspy.Server):
>>> class
Echo
Server(twspy.Server):
>>> def onopen(self, client):
>>> def onopen(self, client):
>>> # client connected
>>> print 'Client %s connected' % client
>>> def onclose(self, client):
>>> # client disconnected
>>> def onmessage(self, client, message):
>>> def onmessage(self, client, message):
>>> # handle message from client
>>> print 'Received message "%s"' % message.payload
>>> client.send(twspy.TextMessage(message.payload))
>>> def onclose(self, client):
>>> print 'Client %s disconnected' % client
>>>
Game
Server(8000).run()
>>>
Echo
Server(8000).run()
"""
"""
def
__init__
(
self
,
port
,
hostname
=
''
,
loglevel
=
logging
.
INFO
,
protocols
=
[],
def
__init__
(
self
,
port
,
hostname
=
''
,
loglevel
=
logging
.
INFO
,
protocols
=
[],
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment