Erlang MUD IV
So, after watching Dennou Coil, I thought back to my idea for a card game. Well, it wasn’t so much an idea for a specific card game, but more along the lines of “lol cards are cool”. The idea came back mostly because of the awesomeness of Metatags in Dennou Coil. Really an awesome series.
Anyway, so I was thinking some more, and you know, card games really aren’t that fun unless you play them with other people. Which means I’m gonna need a server backend for the whole thing. Which means… Erlang!
It’s been a long time since I last thought about it, and you know, it really needs some more thought. The shitty gen_tcp wrapper I wrote a while back is really dumb, and easily killable. Additionally, the network layer needs to not only abstract the client stuff, but it needs to do other tasks like prevent flooding, basic input processing (backspaces…), etc.
So, lulz, I’m once again rewriting the network layer. Because that’s what I seem to do in Erlang. Like many of my “projects” I’ll probably get bored with it after a couple of days, then come back to it at a later date. Here’s the interface that I’ve laid out for it:
-module( mud_serv ). -export( [ start_async/2, serv_listen/2, serv_handle_clients/2, client_listen/3, client_sockrecv/2 ] ). % Primary function, opens a listener port and spawns the listener. % Non-blocking. % % Arguments: % Port - port number to open a listener port on. % ClientFunc - a fun/1 which gets spawned for each client; is given % the PID of the client_listen process for control. Will be passed % { sock_recv, Msg }, { sock_connect } and { sock_disconnect }. % start_async( Port, ClientFunc ) -> ok . % Listener process for the server socket. Waits until a connection is % incoming, and then hands the request to a serv_handle_clients/2 process % which then decides whether or not to accept the connection. Essentially % a gen_tcp:accept blocker. % % Arguments: % ServSock - the pre-created valid socket handle to listen with % serv_listen( ServSock, PID_Handler ) -> ok . % Dedicated process for handling incoming connections and already connected % clients. Maintains a list of clients (and their associted IP addresses and % sockets). Is notified when a client disconnects by client_listen. % % Arguments: % ClientFunc - passed in by start_async/2 % ClientList - a list of currently-connected sockets. % serv_handle_clients( ClientFunc, ClientList ) -> ok . % Process which is spawned for each client; serves as an interface between the % socket and the actual application code. % % Arguments: % ClientSock - the socket handle for the client % PID_Client - PID to the application process handling this client, spawned from % the ClientFunc passed to serve_async/2. % PID_Handler - the PID to the serv_handle_clients/2 process, to notify the % handler process when the client disconnects. % client_listen( ClientSock, PID_Client, PID_Handler ) -> ok . % Process which is spawned for each client; acts as a gen_tcp:recv loop % to allow the socket to be processed in an asynchronous manner. % % Arguments: % ClientSock - the socket handle for the client % PID_Listener - PID to the client_listen/3 process to forward messages % received from the socket. % client_sockrecv( ClientSock, PID_Listener ) -> ok .