Imagine this: you load up a 4chan chat page, and you're connected to another user to chat one on one. Completely at random, with no traces of identity whatsoever. That's it. There could be a button to get a new person if you really don't like who you're talking to or you've seen them before, or you could just hit F5. In the true spirit of Anonymous, you could talk about anything in complete freedom.
I think that could be pretty awesome (and also pretty fail, but such is the way of all things chan), and it's an idea that I've had in the back of my mind for a while. I don't have the wherewithal to make it happen, however, so by /img/'s recommendation I'm here pitching it to /prog/ in the hope that someone will get inspired and make this happen. I'd really like to see it made real. I have to imagine that it would be very simple to make, although finding a good host and getting people to use it is another matter.
Anyone's interest piqued?
Name:
1312007-12-11 1:37
New server: telnet://213.10.200.234:20656/
Does one-to-one chat, heavily modified version of >>131.
start( Port )
->
% Start up the responder so messages can get sent to it.
PID_Responder = spawn( server, responder, [ [] ] ),
% Create the server socket and start the server
case gen_tcp:listen( Port, [ list, { active, false }, { packet, line } ] ) of
{ ok, ServSock }
->
{ ok, Port } = inet:port( ServSock ),
io:format( "Listening on port ~w.~n", [ Port ] ),
listen( ServSock, PID_Responder, invalid, 0, [] );
{ error, Reason }
->
{ error, Reason }
end
.
listen( ServerSock, PID_Responder, LastIP, IPtimes, BannedIPs )
->
% Grab the client attempting to connect
case gen_tcp:accept( ServerSock, 5 * 60 * 1000 ) of
{ ok, ClientSock }
->
% IP checking and banning
{ ok, { IP, _ } } = inet:peername( ClientSock ),
io:format( "Client connected from ~p!~n", [ IP ] ),
case lists:member(IP, BannedIPs) of
true
->
gen_tcp:send( ClientSock, "B&\n" ),
gen_tcp:close( ClientSock ),
listen( ServerSock, PID_Responder, IP, 0, BannedIPs );
false
->
% Set up the thread to listen for that client
spawn( server, client, [ClientSock, PID_Responder] ),
case IP == LastIP of
true
->
case IPtimes < 10 of
true
->
listen( ServerSock, PID_Responder, IP, IPtimes + 1, BannedIPs );
false
->
listen( ServerSock, PID_Responder, IP, 0, [ IP | BannedIPs ] )
end
;
false
->
listen( ServerSock, PID_Responder, IP, 0, BannedIPs )
end
end
;
Other
->
io:format( "gen_tcp:accept returned ~p. Quitting.~n", [ Other ] )
end
.
client( ClientSock, PID_Responder )
->
% Welcome message
gen_tcp:send( ClientSock,
"HAVE YOU READ YOUR SICP TODAY?
Use /next to ditch current chatpartner.
Use /echo to toggle echoing.
Waiting for a chatter...\n"),
% Make thread to handle connection
spawn( server, client_listen, [ ClientSock, self() ] ),
% Add to list of available chatters
PID_Responder ! { add_client, self() },
% Go into the main loop
client_mainloop( ClientSock, PID_Responder, nope, false )
.
client_mainloop( ClientSock, PID_Responder, Otherperson, Echo )
->
receive
{ toggle_echo }
->
gen_tcp:send( ClientSock,
io_lib:format("Echo mode set to ~p~n", [ not Echo ] )),
client_mainloop( ClientSock, PID_Responder, Otherperson, not Echo );
{ die }
->
case Otherperson of
nope
->
ok;
PID
->
PID ! { disconnected }
end
,
PID_Responder ! { remove_client, self() },
{ send_message, Message }
->
case Otherperson of
nope
->
ok;
PID
->
case Echo of
true
->
gen_tcp:send( ClientSock,
io_lib:format("<Me> ~s~n", [ Message ] ) );
false
->
ok
end
,
PID ! { message, Message }
end
,
% Loop
client_mainloop( ClientSock, PID_Responder, Otherperson, Echo )
end
.
isprintable( Character )
->
Character >= 32 andalso Character =< 126
.
client_listen( ClientSock, ClientPID )
->
% Just wait for something to happen.
case gen_tcp:recv( ClientSock, 0 ) of
{ ok, RawMsg }
->
Msg = lists:filter( fun isprintable/1, RawMsg ),
case lists:sublist(Msg, 5) of
"/next"
->
ClientPID ! { disconnect };
"/echo"
->
ClientPID ! { toggle_echo };
_
->
ClientPID ! { send_message, Msg }
end
,
% Loop
client_listen( ClientSock, ClientPID );
{ error, _ }
->
gen_tcp:close(ClientSock),
ClientPID ! { die }
end
.
random2( Max )
->
% Get two random numbers 1 <= x <= Max
Random1 = random:uniform( Max ),
Random2 = random:uniform( Max ),
case Random1 == Random2 of
true
->
random2( Max );
false
->
{Random1, Random2}
end
.