WebSocketServer.socket() is a static method takes a host and port and
an optional connect parameter. If connect is not set then it returns
a socket listening on host and port. If connect is set then
a connection will be made host and port and the socket returned. This
has IPv6 support like the addrinfo method it replaces.
Also, prefer IPv4 resolutions if they are in the list. This can be
overriden to prefer IPv6 resolutions for the same host using the
optional prefer_ipv6 parameter.
- fix addrinfo to accept empty host as localhost
- use correct host variable in addrinfo error message
- accept HyBi 7, 8 and 9. No difference for now.
- send close buffer correctly.
WebSocketServer(..., record='FILE_PREFIX')
The reocrd parameter will turn on recording of all messages sent
to and from the client. The record parameter is a file prefix. The
full file-name will be the prefix with an extension '.HANDLER_ID'
based on the handler ID.
Recording required some restructing of the encode and decode function
to return more information so that the recording functions can record
just the payload data and ignore the WebSockets framing/headers.
Caveats:
- Not all messages recorded as sent to the client were necessarily
received by the client. For example, if several messages are queued
for the client, but the connection is shutdown before the messages
are actually sent, these queued messages will still appear in the
recording.
- If the server is also handling HTTP requests then the handler ID
extensions for the recorded files will be monotonic but not
contiguous because only WebSocket connections are recorded, not HTTP
requests.
Ticket #2: https://github.com/kanaka/websockify/issues/2 - win32
support. The 'resource' module is not available under Windows. We only
use it for daemonizing so make it optional and disable daemonizing
support on Windows for now.
Also, refactor how the optional imports to turn them into data instead
of code and iterate through them.
Add early warnings to indicate when modules are missing and
functionality is disabled.
Multiprocessing:
- Switch to using multiprocessing module for python >= 2.6. For python
2.4 continue to use the os.fork() method.
- Move the new_client creation into top_new_client method to enable
multiprocessing refactor.
- Only do SIGCHLD handling for os.fork/python 2.4. When doing our own
SIGCHLD handling under python 3.0, we can run into a python futex
hang when reloading a web page rapidly. Multiprocessing does it's
own child reaping so we only need it with os.fork().
Python 3.0:
- Modify imports to reflect new locations: StringIO from io,
SimpleHTTPRequestHandler from http.server, urlsplit from
urllib.parse.
- Convert all print statements to print() calls. This also means no
comma parameter idiom and only using string formatting.
- Define b2s (bytes-to-string) and s2b (string-to-bytes) which are
no-ops on python versions prior to python 3. In python 3 these do
the conversion between string and bytes.
- Use compatible try/except method. Exception variable must be
extracted using sys.exc_info() rather than as part of the except
statement.
Python 2.4:
- Now degrades more gracefully if ssl module is not found. It will
still run, but will refuse SSL connections.
- Doesn't support HyBi-07 version due to numpy and struct.unpack_from
requirement.
Instead of doing crazy things with file-descriptors in
SplitHTTPHandler, WSRequestHandler detects a WebSockets upgrade and
returns 101 as the 'last_code'. In addition to avoiding funkiness with
file-descriptors, this allows use of the already parsed headers and
removal of the parse_handshake routine.
This also makes it easier to explore adding python 3.X support
(https://github.com/kanaka/websockify/issues/1) since the
file-descriptor/string splitting is very difficult to integrate with
python 3.X.
- Add initial IETF-07 (HyBi-07) protocol version support. This version
still uses base64 encoding since the API for binary support is not
yet finalized.
- Move socket send and recieve functions into the WebSocketServer
class instead of having the sub-class do this. This simplifies
sub-classes somewhat. The send_frame routine now returns the number
of frames that were unable to be sent. If this value is non-zero
then the sub-class should call again when the socket is ready until
the pending frames count is 0.
- Do traffic reporting in the main class instead.
- When the client is HyBi style (i.e. IETF-07) then use the
sub-protocol header to select whether to do base64 encoding or
simply send the frame data raw (binary). Update include/websock.js
to send a 'base64' protocol selector. Once the API support binary,
then the client will need to detect this and set the protocol to
'binary'.
Primary change is removal of FABridge interface.
Seems to improve overall latency by perhaps 10%. Also, the slowdown
over time in Opera is about half as bad (but still there).