Closed chomwitt closed 8 years ago
Can you show us your ws_server_side:init/1
function? It's getting a case clause
exception, so there's some case for something it's not handling, and it crashes the process.
init(_Args) -> Pid = spawn(fun() -> loop(0) end), case whereis(counter) of undefined -> register(counter, Pid); Pid -> ok end, {ok,first}.
Your whereis(counter)
call is clearly not returning undefined
, as you'd get no error in that case. It's returning a pid which is not equal to Pid
, which means that an older process is already registered with the name counter
, and so your case
fails.
One way to fix this is to only start the new process when it's actually needed:
init(_Args) ->
case whereis(counter) of
undefined ->
register(counter, spawn(fun() -> loop end));
_Pid -> ok
end,
{ok,first}.
But an overall problem is that I'm not sure how you're stopping any existing counter
processes. Ideally, they'd be supervised in some fashion to prevent them from leaking, rather than simply being spawned like this.
I see your point . in my counter webapp i have a exit button that will stop the counter process and unregister its name . But i wasnt sure in the case of succesive ' new Websocket(url)' calls what will happen. Is it sth that i must take care of or the websocket protocols would 1) either not allow a new websocket to the same server/port/resource from the same cliient while one is open 2)either will close the existing one and try to create a new websocket
From RFC 6445 p.15
If the client already has a WebSocket connection to the remote host (IP address) identified by /host/ and port /port/ pair, even if the remote host is known by another name, the client MUST wait until that connection has been established or for that connection to have failed. There MUST be no more than one connection in a CONNECTING state. If multiple connections to the same IP address are attempted simultaneously, the client MUST serialize them so that there is no more than one connection at a time running through the following steps.
You might consider using a supervisor to start a gen_server
to implement your counter, and then your websocket callbacks can just assume the counter
process is already there.
Sorry if i insist, but the more i think some basic use cases for an erlang/yaws websocket based webapp the more i get lost.
For example i read in : https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API/Writing_WebSocket_servers#Keeping_track_of_clients
Keeping track of clients
This doesn't directly relate to the WebSocket protocol, but it's worth mentioning here: your server will have to keep track of clients' sockets so you don't keep handshaking again with clients who have already completed the handshake. The same client IP address can try to connect multiple times (but the server can deny them if they attempt too many connections in order to save itself from Denial-of-Service attacks).
So for a simple webapp like the basic echo in yaws'manual how can a server differentiate that 'two instances' of the webapp have started when a user just opened the same url in two tabs, meaning that the client endpoint(in websocket parlance) will be the same?
Not sure I understand the question. An endpoint is determined by a socket representing a connection, and a connection consists of a 5-tuple that included protocol (in this case TCP), client IP address, client port, server IP address, and server port. The 5-tuple for each endpoint of the webapp will be unique even if it's coming from the same client host.
In a simple erlang/yaws webapp i made if the client asks for a websocket connection while a websocket connection is already open the app will broke and yaws (interactive session) throws:
=ERROR REPORT==== 10-Aug-2016::02:55:32 === Failed to start websocket process: {{case_clause,<0.90.0>}, [{ws_server_side,init,1, [{file,"ws_server_side.erl"},{line,15}]}, {yaws_websockets,init,1, [{file,"yaws_websockets.erl"}, {line,167}]}, {gen_server,init_it,6, [{file,"gen_server.erl"},{line,306}]}, {proc_lib,init_p_do_apply,3, [{file,"proc_lib.erl"},{line,237}]}]}
My websocket callbackmodule's init function will just spawn and register a process.