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
d4c3c564
Commit
d4c3c564
authored
Dec 20, 2014
by
Taddeüs Kroes
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Updated README
parent
1dec97be
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
121 additions
and
75 deletions
+121
-75
README.md
README.md
+121
-75
No files found.
README.md
View file @
d4c3c564
...
@@ -11,10 +11,11 @@ easily set up a web server. Thus, it is both suited for quick server
...
@@ -11,10 +11,11 @@ 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
programming, as well as for more demanding applications that require low-level
control over each frame being sent/received.
control over each frame being sent/received.
Her is a quick overview of the features in this library:
Her
e
is a quick overview of the features in this library:
-
Upgrading regular sockets to web sockets.
-
Upgrading regular sockets to web sockets.
-
Building custom frames.
-
Building custom frames (see "Sending frames with a websocket").
-
Messages, which are higher-level than frames (see "Basic usage").
-
Messages, which are higher-level than frames (see "Sending messages with a a
connection").
-
Connections, which hide the handling of control frames and automatically
-
Connections, which hide the handling of control frames and automatically
concatenate fragmented messages to individual payloads.
concatenate fragmented messages to individual payloads.
-
HTTP authentication during handshake.
-
HTTP authentication during handshake.
...
@@ -24,98 +25,137 @@ Her is a quick overview of the features in this library:
...
@@ -24,98 +25,137 @@ Her is a quick overview of the features in this library:
[
deflate-frame
](
http://tools.ietf.org/html/draft-tyoshino-hybi-websocket-perframe-deflate-06
)
[
deflate-frame
](
http://tools.ietf.org/html/draft-tyoshino-hybi-websocket-perframe-deflate-06
)
and
and
[
permessage-deflate
](
http://tools.ietf.org/html/draft-ietf-hybi-permessage-compression-17
)
.
[
permessage-deflate
](
http://tools.ietf.org/html/draft-ietf-hybi-permessage-compression-17
)
.
-
Asynchronous sockets with an EPOLL-based server
.
-
Threaded and asynchronous (EPOLL-based) server implementations
.
Installation
Installation
============
============
Us
e Python's package manager
:
Us
ing Python's package manager (note: this seems to be bugged atm)
:
easy_install wspy
easy_install wspy
pip install wspy
pip install wspy
Using Git inside your project:
Basic usage
git submodule add https://github.com/taddeus/wspy.git
===========
-
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:
Getting Started
===============
import wspy, socket
The following example is an echo server (sends back what it receives) and can
sock = wspy.websocket()
be used out of the box to connect with a browser. The API is similar to that of
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
web sockets in JavaScript:
sock.bind(('', 8000))
sock.listen(5)
client = sock.accept()
import logging
client.send(wspy.Frame(wspy.OPCODE_TEXT, 'Hello, Client!'))
import wspy
frame = client.recv()
Client example:
class EchoServer(wspy.AsyncServer):
def onopen(self, client):
print 'Client %s connected' % client
import wspy
def onmessage(self, client, message):
sock = wspy.websocket(location='/my/path')
print 'Received message "%s"' % message.payload
sock.connect(('', 8000))
client.send(wspy.TextMessage(message.payload))
sock.send(wspy.Frame(wspy.OPCODE_TEXT, 'Hello, Server!'))
-
A
`Connection`
instance represents a connection between two end points, based
def onclose(self, client, code, reason):
on a
`websocket`
instance. A connection handles control frames properly, and
print 'Client %s disconnected' % client
sends/receives messages (
`Message`
instances, which are higher-level than
frames). Messages are automatically converted to frames, and received frames
are converted to messages. Fragmented messages (messages consisting of
multiple frames) are also supported.
Example of an echo server (sends back what it receives):
EchoServer(('', 8000),
extensions=[wspy.DeflateMessage(), wspy.DeflateFrame()],
loglevel=logging.DEBUG).run()
import socket
Corresponding client code (JavaScript, run in browser):
import wspy
class EchoConnection(wspy.Connection):
ws = new WebSocket('ws://localhost:8000');
def onopen(self):
ws.onopen = function() {
print 'Connection opened at %s:%d' % self.sock.getpeername()
console.log('open');
this.send('Hello, World!');
};
ws.onmessage = function(e) {
console.log('message', e.data);
};
ws.onerror = function() {
console.log('error');
};
ws.onclose = function(e) {
console.log('close', e.code, e.reason);
};
def onmessage(self, message):
print 'Received message "%s"' % message.payload
self.send(wspy.TextMessage(message.payload))
def onclose(self, code, reason):
Sending frames with a websocket
print 'Connection closed'
===============================
server = wspy.websocket()
The
`websocket`
class upgrades a regular socket to a web socket. A
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
`websocket`
instance is a single end point of a connection. A
`websocket`
server.bind(('', 8000))
instance sends and receives frames (
`Frame`
instances) as opposed to bytes
server.listen(5)
(which are sent/received in a regular socket).
while True:
Server example:
client, addr = server.accept()
EchoConnection(client).receive_forever()
There are two types of messages:
`TextMessage`
s and
`BinaryMessage`
s. A
import wspy, socket
`TextMessage`
uses frames with opcode
`OPCODE_TEXT`
, and encodes its payload
sock = wspy.websocket()
using UTF-8 encoding. A
`BinaryMessage`
just sends its payload as raw data.
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
I recommend using
`TextMessage`
by default, and
`BinaryMessage`
only when
sock.bind(('', 8000))
necessary.
sock.listen(5)
**Note:**
For browser clients, you will probably want to use JSON encoding.
client = sock.accept()
This could, for example, be implemented as follows:
client.send(wspy.Frame(wspy.OPCODE_TEXT, 'Hello, Client!'))
frame = client.recv()
import wspy, json
Client example:
def msg(**data):
import wspy
return wspy.TextMessage(json.dumps(data))
sock = wspy.websocket(location='/my/path')
sock.connect(('', 8000))
sock.send(wspy.Frame(wspy.OPCODE_TEXT, 'Hello, Server!'))
# create some connection `conn`...
conn.send(msg(foo='Hello, World!'))
Sending messages with a connection
==================================
A
`Connection`
instance represents a connection between two end points, based
on a
`websocket`
instance. A connection handles control frames properly, and
sends/receives messages (
`Message`
instances, which are higher-level than
frames). Messages are automatically converted to frames, and received frames
are converted to messages. Fragmented messages (messages consisting of
multiple frames) are also supported.
Built-in servers
Example of an echo server (sends back what it receives):
================
import socket
import wspy
class EchoConnection(wspy.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(wspy.TextMessage(message.payload))
def onclose(self, code, reason):
print 'Connection closed'
server = wspy.websocket()
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server.bind(('', 8000))
server.listen(5)
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.
Managing connections with a server
==================================
Threaded
Threaded
--------
--------
...
@@ -131,26 +171,26 @@ also receive an additional `client` argument. The client argumetn is a modified
...
@@ -131,26 +171,26 @@ also receive an additional `client` argument. The client argumetn is a modified
For example, the
`EchoConnection`
example above can be rewritten to:
For example, the
`EchoConnection`
example above can be rewritten to:
import wspy
import wspy
class EchoServer(wspy.Server):
class EchoServer(wspy.Server):
def onopen(self, client):
def onopen(self, client):
print 'Client %s connected' % client
print 'Client %s connected' % client
def onmessage(self, client, message):
def onmessage(self, client, message):
print 'Received message "%s"' % message.payload
print 'Received message "%s"' % message.payload
client.send(wspy.TextMessage(message.payload))
client.send(wspy.TextMessage(message.payload))
def onclose(self, client, code, reason):
def onclose(self, client, code, reason):
print 'Client %s disconnected' % client
print 'Client %s disconnected' % client
EchoServer(('', 8000)).run()
EchoServer(('', 8000)).run()
The server can be stopped by typing CTRL-C in the command line. The
The server can be stopped by typing CTRL-C in the command line. The
`KeyboardInterrupt`
raised when this happens is caught by the server.
`KeyboardInterrupt`
raised when this happens is caught by the server.
Asynchronous
Asynchronous
(recommended)
------------
------------
--------------
The
`AsyncServer`
class has the same API as
`Server`
, but uses
The
`AsyncServer`
class has the same API as
`Server`
, but uses
[
EPOLL
](
https://docs.python.org/2/library/select.html#epoll-objects
)
instead of
[
EPOLL
](
https://docs.python.org/2/library/select.html#epoll-objects
)
instead of
...
@@ -164,3 +204,9 @@ Extensions
...
@@ -164,3 +204,9 @@ Extensions
==========
==========
TODO
TODO
Secure sockets with SSL
=======================
TODO
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