Rawsocket vs Websocket, what are the differences?

In the process of building a python app relying on asynchronous web services, i found myself using crossbar.io in order to make Remote Protocol Calls(RPC) via the package autobahn.

When time came to optimize my app, i tested two configurations for transportation on my router: rawsocket and websocket, and the timings were drastically different !

With a batch of 20 requests, all sent concurrently and handled in threads (so transportation is the main bottleneck), with a payload of size 800Kb ( np.random.random(100000) ) and i got this kind of results :

Websocket: ~ 2.7 s
Rawsocket: ~ 0.6 s

Why is there such a big timing difference ? I came to realize that websocket is “waiting” for a message transmission to finish in order to send the next one, is that different in rawsocket ? What are the differences between rawsockets and websockets in this context and what limitation should i take into account ?

WebSocket is an HTTP-based standard and rawsocket is something unique to crossbar … essentially just a TCP connection plus message framing. So, yes, fairly different in their details.

Did you make sure you have the same WAMP-level serializer for both tests? JSON e.g. will be much slower than anything else (msgpack, cbor etc).

If you can point to your benchmark code, that would be interesting!

Oh, your last question is kind of about multiplexing. Both protocols send one complete message at a time, in-order.

Thank you for your answer,

I can’t give you a working code snippet, but here is the relevant code:

The service (rpc):

def bench_test_size(self, size):
   payload = np.random.random(size)
#we noticed that serializing a np array may increase dumps() size by 50% 
#in some obscure conditions so i stick with tolist().
   payload = payload.tolist() 

   return payload

The test:

async def test_call(wampsession):
    size = 100000
    ret = await wampsession.call("bench.test.size", size)

Which i call n times via:

async def call_n_times(wampsession, n)
    await asyncio.gather(*[test_call(wampsession) for _ in range(n)])

I would first make sure that you’re using the same serializer in both cases (probably by configuring just a single one for websocket and the same one for rawsocket). I expect that to make a way bigger difference than rawsocket vs websocket. d