Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

Re^2: Mojolicious: Websocket example under hypnotoad

by farkhadbek (Initiate)
on Jul 09, 2014 at 08:55 UTC ( #1092866=note: print w/replies, xml ) Need Help??


in reply to Re: Mojolicious: Websocket example under hypnotoad
in thread Mojolicious: Websocket example under hypnotoad

This is an example of chat application.

This is Mojolicious application and it can be run in different ways.

One of the ways to run under the hypnotoad.

What is Hypnotoad?

Hypnotoad is a full featured, UNIX optimized, preforking non-blocking I / O HTTP and WebSocket server, built around the very well tested and reliable Mojo :: Server :: Prefork, with IPv6, TLS, Comet (long polling), keep-alive, connection pooling, timeout, cookie, multipart, multiple event loop and hot deployment support that just works.

Hypnotoad is PREFORKING server therefore has many processes (workers). Variable $clients contains references to objects Mojo::Transaction. This object is required for calling send_message (send a message to the chat user)

The problem is that this variable is not shared between workers. And connected users in the one worker are not visible in another.

I'm trying to solve this problem.

If you are after these explanations did not understand anything then do not worry about it

Thanks

  • Comment on Re^2: Mojolicious: Websocket example under hypnotoad

Replies are listed 'Best First'.
Re^3: Mojolicious: Websocket example under hypnotoad
by Corion (Pope) on Jul 09, 2014 at 09:40 UTC

    I think you will have to add much more session handling and inter-server communication for making the "real-time" aspect of WebSockets work across multiple processes. Personally, I would try really hard to avoid this, for example by moving the non-WebSocket parts of your application to a different machine/CPU/process.

    If you still want to go the route of keeping one WebSocket open to each client but have communication between them, you will need to have communication between your server processes too, to move the information from the other parts of your application to the process that holds the socket of the client. I think this is where message brokers like ZeroMQ come in to make IPC easier. Other people use HTTP as their internal transport ("SOA" respectively "microservices").

    I think that the multi-process approach massively complicates your infrastructure and setup, but if there is no easy way to handle this within one process then you'll have to look in that direction.

Re^3: Mojolicious: Websocket example under hypnotoad
by Anonymous Monk on Jul 09, 2014 at 23:05 UTC

    The problem is that this variable is not shared between workers. And connected users in the one worker are not visible in another.

    Ok, thats, easy, use a database for IPC, store all the messages in a database, then all the workers can get messages from this database (or service)

    Then it doesn't matter which worker the clients are connected to, they all get messages from database

    This is arranged by poling, see https://metacpan.org/pod/Mojolicious::Guides::Cookbook#Timers

    So something like this (maybe with more smaller events ->on and what not)

    use Mojo::IOLoop; my $clients = {}; my $lasttime = time; Mojo::IOLoop->recurring( 1 => sub { if ( my( $newMessages, $time ) = GetNewFromDb($lasttime) ) { $lasttime = $time; for my $msg (@$newMessages) { MsgToClients( $msg, $clients ); } } }, ); websocket '/echo' => sub { ... $self->receive_message( sub { my ($self, $msg) = @_; MsgToDb( $self, $msg ); ## NO ## MsgToClients( $self, $msg , $clients ); ## NO }, ); ... }; sub GetNewFromDb { my( $lasttime ) = @_; ... my $time = eval { $last_message->{time} }; return $messages, $time; }

    instead of $lasttime being time based, might be better to use last_insert_id of some sort from the database or some such .... details :)

    update: found the converstation

    http://irclog.perlgeek.de/mojo/2013-06-26#i_7255079

    20:15 ghandi Hi There! I've been playing around with the Mojo +WebSocket Chat-Example from https://github.com/kraih/mojo/wiki/Writi& +#8203;ng-websocket-chat-using-Mojolicious-Lite 20:15 And now i'm wondering: Do i realy need to keep track of +the clients myself in %clients? Wouldn't it be cooler to just use a c +ustom event that i emit on a new incoming message? 20:16 gtodd hmm 20:17 define "cooler" :-) 20:17 Anyway maybe you could answer questions about Mojo on St +ackoverflow and become famous :) 20:17 there's one up there about websockets ... 20:17 for me cooler would be "faster" 20:18 ghandi cooler like more slick 'n sexy. Like let the Even +t-System take care of the Client-Management since it already knows ab +out the connections 20:18 gtodd POE could be sexy but Mojo-POE I don't know 20:20 sri ghandi: no, in fact, that example is not very good t +o begin with 20:20 doesn't scale past one process 20:20 gtodd ghandi: what you just described seems too easy or +obvious 20:21 oops hehe I agree with sri 20:21 sri it's a minimal example, anything serious needs a bac +kend like redis pub/sub 20:21 gtodd ghandi: btw. I meant too obvious or easy because i +t makes sense to me and I am usually wrong :-) 20:22 ghandi so in my case: I'm thinking about some live-intar +action page, where multiple people whatch the page while a single per +son sends in some updates. For this i need a dedicated "collaboration +"-Server to which mojo talks? 20:26 btyler like sri said, redis with pub/sub is precisely th +at 'middle person' that multiple mojo processes can talk to 20:27 ghandi But don't i loose then the event-driven part of t +he Websockets? The client then has to poll the app which then will lo +okup on redis? 20:28 sri i think Mojo::Redis is actually battle tested now wi +th wirc using pub/sub too 20:30 batman: Mojo::JSON uses render_json in the example 20:30 Drossel joined #mojo 20:31 bek ghandi: /quit 20:33 ghandi sri: Mojo::Redis looks interesting. So just to ge +t something right: The Mojo-Event-System is Process-Based, right? Whi +ch means: Client A on $PID 1 can't talk to Client B on $PID 2? 20:34 sri that's how everything in perl works 20:35 ghandi Ok, thanks ;)

    So there is the context, use Mojo::Redis - Asynchronous Redis client for Mojolicious. somehow

    Redis - Perl binding for Redis database

    Redis is an open-source, networked, in-memory, key-value data store with optional durability. It is written in ANSI C. The name Redis means REmote DIctionary Server The Publish/Subscribe feature is fully implemented, so a client of a slave may SUBSCRIBE to a channel and receive a full feed of messages PUBLISHed to the master,

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://1092866]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others romping around the Monastery: (6)
As of 2020-07-08 14:12 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?