A WebSockets library for Julia
Julia HTML JavaScript
Clone or download
hustf Benchmarks still missing on 1.0 due to IndexedTables. Removed HttpSer…
…ver tests. (#109)

modified:   README.md                 rephrasing
modified:   benchmark/REQUIRE         remove HTTP
modified:   benchmark/benchmark.jl    remove HTS
deleted:    benchmark/logs/benchmark_results_readable.log
modified:   benchmark/ws_jce.jl       Don't use HTTP
deleted:    examples/serve_verbose/svg/ws_neighborhood.svg
deleted:    logutils/log_httpserver.jl
modified:   logutils/log_ws.jl        Don't use Requires
modified:   logutils/logutils_ws.jl   Don't use Requires
deleted:    test/optional/browsertest.html
deleted:    test/optional/browsertest.jl
deleted:    test/optional/browsertest2.html
deleted:    test/optional/favicon.ico
deleted:    test/optional/functions_log_test.jl
deleted:    test/optional/functions_open_browsers.jl
deleted:    test/optional/functions_server.jl
deleted:    test/optional/handler_functions_events.jl
deleted:    test/optional/handler_functions_websockets_general_test.jl
deleted:    test/optional/handler_functions_websockets_subprotocol_test.jl
deleted:    test/optional/phantom.js
Latest commit 33f2905 Aug 14, 2018



Release version:

WebSockets Build Status Coverage Status

Development version:

WebSockets Build Status Coverage Status Appveyor

Server and client side Websockets protocol in Julia. WebSockets is a small overhead message protocol layered over TCP. It uses HTTP(S) for establishing the connections.

Getting started

On Julia pre 0.7, see an earlier version of this repository.

(v0.7) pkg>add WebSockets
julia> using WebSockets
julia> varinfo(WebSockets)
help?> serve
help?> WebSockets.open
julia> cd(joinpath((WebSockets |> Base.pathof |> splitdir)[1],  "..", "examples"))
julia> readdir()
julia> include("chat_explore.jl")

Open a client side connection

Client side websockets are created by calling WebSockets.open (with a server running somewhere). Example (you can run this in a second REPL, or in the same):

julia> cd(joinpath((WebSockets |> Base.pathof |> splitdir)[1],  "..", "examples"))
julia> include("client_repl_input.jl")

We recommend readguarded and writeguarded instead of readand write for more effective debugging.

Debugging server side connections

Server side websockets are asyncronous tasks, which makes debugging harder. The error messages may not spill into the REPL. There are two interfaces to starting a server which includes a websocket handling function:

Using WebSockets.serve

Error messages are directed to a channel. See inline docs: ?Websockets.serve.

Using HTTP.listen

Error messages are by default sent as messages to the client. This is not good practice if you're serving pages to the internet, but nice while developing locally.

What is nice with WebSockets.jl?

Some packages rely on WebSockets for communication. You can also use it directly:

  • reading and writing between entities you can program or know about
  • low latency, high speed messaging
  • implementing your own 'if X send this, Y do that' subprotocols
  • registered websocket subprotocols for e.g. remote controlled hardware
  • heartbeating, relaying user interaction to backend simulations
  • build a network including browser clients
  • convenience functions for gatekeeping
  • putting http handlers and websocket coroutines ('handlers') in the same process can be a security advantage. It is good practice to modify web page responses to include time-limited tokens in the wsuri.

WebSockets are well suited for user interactions via a browser or cross-platform applications like electron. Workload and development time can be moved off Julia resources, error checking code can be reduced. Use websockets to pass arguments between compiled functions on both sides; it has both speed and security advantages over passing code for evaluation.

The /logutils folder contains some specialized logging functionality that is quite fast and can make working with multiple asyncronous tasks easier. See /benchmark code for how to use. Logging may be moved entirely out of WebSockets.jl in the future.

You can also have a look at alternative Julia packages: DandelionWebSockets or the implementation currently part of HTTP.jl.

What are the main downsides to using WebSockets.jl directly?

  • Logging. We need customizable and very fast logging for building networked applications.
  • Compression is not implemented.
  • Possibly non-compliant proxies on the internet, company firewalls.
  • 'Warm-up', i.e. compilation when a method is first used. Warm-up is excluded from current benchmarks.
  • Garbage collection, which increases message latency at semi-random intervals. See benchmark plots.
  • If a connection is closed improperly, the connection task will throw uncaught ECONNRESET and similar messages.
  • TCP quirks, including 'warm-up' time with low transmission speed after a pause. Heartbeats can alleviate.
  • Since read is a blocking function, you can easily end up reading indefinitely from any side of the connection. See the `close function code for an example of non-blocking read with a timeout.

Errors after updating?

The introduction of client side websockets to this package in version 0.5.0 may require changes in your code:

  • The WebSocket.id field is no longer supported. You can generate unique counters by code similar to 'bencmark/functions_open_browsers.jl' COUNTBROWSER.
  • You may want to modify you error handling code. Examine WebSocketsClosedError.message.
  • You may want to use readguarded and writeguarded to save on error handling code.
  • Server -> WebSockets.ServerWS
  • WebSocketHandler -> WebSockets.WebsocketHandler (or just pass a function without wrapper)
  • HttpHandler-> HTTP.HandlerFunction (or just pass a function without wrapper)
  • run -> serve
  • Response -> HTTP.Response
  • Request -> HTTP.Response

You may also want to consider using target, orginand subprotocol, which are compatible with both of the types above.

::            ::
::  Made at   ::
::            ::
 Recurse Center