Chat server: Difference between revisions

m
syntax highlighting fixup automation
(Added Wren)
m (syntax highlighting fixup automation)
Line 10:
{{libheader|AdaSockets}}
 
<langsyntaxhighlight lang=Ada>with Ada.Containers.Vectors;
with Ada.Command_Line; use Ada.Command_Line;
with Ada.Exceptions; use Ada.Exceptions;
Line 94:
Dummy.Start (Incoming_Socket);
end loop;
end Chat_Server;</langsyntaxhighlight>
 
=={{header|BaCon}}==
Requires BaCon 4.2 or higher. Clients have to login with an alias and can use the commands 'say' or 'quit'. Notifications are submitted when users enter the chat or leave the chat.
<syntaxhighlight lang=text>DECLARE user$ ASSOC STRING
DECLARE connect ASSOC long
OPEN "localhost:51000" FOR SERVER AS mynet
Line 132:
ENDIF
ENDIF
WEND</langsyntaxhighlight>
 
=={{header|C}}==
Line 141:
A glitch occurs if a connection is made using the Telnet protocol - user names are preceded by garbled text.
 
<langsyntaxhighlight lang=c>#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
Line 388:
 
return 0;
}</langsyntaxhighlight>
 
=={{header|C sharp|C#}}==
<langsyntaxhighlight lang=csharp>using System;
using System.Collections.Generic;
using System.Net.Sockets;
Line 534:
}
}
}</langsyntaxhighlight>
 
=={{header|CoffeeScript}}==
This is ported from the JavaScript version. The tool js2coffee got me a mostly working version, and then I manually converted JS-style classes to CS "classic-style class" syntax.
 
<langsyntaxhighlight lang=coffeescript>
net = require("net")
sys = require("sys")
Line 647:
 
server = new ChatServer()
</syntaxhighlight>
</lang>
 
=={{header|D}}==
<syntaxhighlight lang=d>
<lang d>
import std.getopt;
import std.socket;
Line 810:
}
}
</syntaxhighlight>
</lang>
 
=={{header|Common Lisp}}==
Line 835:
*USER-MANAGER*, or upon an error occurring.
 
<langsyntaxhighlight lang=common-lisp>
(ql:quickload '(:usocket :simple-actors :bordeaux-threads))
 
Line 1,011:
 
(make-thread #'accept-connections)
</syntaxhighlight>
</lang>
 
=={{header|Erlang}}==
<langsyntaxhighlight lang=erlang>
-module(chat).
 
Line 1,078:
Response -> Response
end.
</syntaxhighlight>
</lang>
 
=={{header|Go}}==
Line 1,087:
This example handles the case of one specific client "falling behind" by relying on the underlying TCP stack to do a reasonable job of buffering. Once that buffer fills, a write to the that client's connection will time out and the connection will dropped. Other minor improvements would include enabling TCP keep alives, handling temporary errors from accept, and better logging. Not ideal, but it should be good enough for this example.
 
<langsyntaxhighlight lang=go>package main
 
import (
Line 1,268:
}
c.server.rem <- c.name
}</langsyntaxhighlight>
 
=={{header|Groovy}}==
{{trans|Java}}
<langsyntaxhighlight lang=groovy>class ChatServer implements Runnable {
private int port = 0
private List<Client> clientList = new ArrayList<>()
Line 1,427:
new ChatServer(port).run()
}
}</langsyntaxhighlight>
 
=={{header|Haskell}}==
<langsyntaxhighlight lang=haskell>{-# LANGUAGE OverloadedStrings #-}
import Network
import System.IO
Line 1,514:
T.putStrLn "Server started"
newMVar (M.empty) >>= clientLoop server
</syntaxhighlight>
</lang>
 
==Icon and {{header|Unicon}}==
 
This is Unicon-specific:
<langsyntaxhighlight lang=unicon>global mlck, nCons, cons
 
procedure main()
Line 1,545:
critical mlck: nCons -:= 1
}
end</langsyntaxhighlight>
 
=={{header|Java}}==
Line 1,553:
I think ideally, NIO would be used to select() sockets available/ready for I/O, to eliminate the possibility of a bad connection disrupting the server, but this increases the complexity.
 
<langsyntaxhighlight lang=java>import java.io.*;
import java.net.*;
import java.util.*;
Line 1,705:
}
}
</syntaxhighlight>
</lang>
 
=={{header|JavaScript}}==
{{works with|Node.js}}
<langsyntaxhighlight lang=javascript>const net = require("net");
const EventEmitter = require("events").EventEmitter;
Line 1,856:
// Start the server!
server = new ChatServer();</langsyntaxhighlight>
 
=={{header|Julia}}==
Modified to fit the Rosetta Code task from example code for the WebSockets module written by Leah Hanson.
To test, start the code and use a browser to connect to localhost:8000.
<langsyntaxhighlight lang=julia>
using HttpServer
using WebSockets
Line 1,944:
println("Chat server listening on 8000...")
run(server,8000)
</syntaxhighlight>
</lang>
 
=={{header|Kotlin}}==
{{trans|Java}}
<langsyntaxhighlight lang=scala>import java.io.BufferedReader
import java.io.IOException
import java.io.InputStreamReader
Line 2,100:
}
}
}</langsyntaxhighlight>
 
=={{header|Nim}}==
<langsyntaxhighlight lang=nim>import asyncnet, asyncdispatch
 
type
Line 2,144:
 
asyncCheck serve()
runForever()</langsyntaxhighlight>
 
=={{header|Objeck}}==
<langsyntaxhighlight lang=objeck>
use System.IO.Net;
use System.Concurrency;
Line 2,257:
}
}
</syntaxhighlight>
</lang>
 
=={{header|Ol}}==
<langsyntaxhighlight lang=scheme>
(define (timestamp) (syscall 201 "%c"))
 
Line 2,329:
 
(run 8080)
</syntaxhighlight>
</lang>
{{Out}}
 
Line 2,387:
=={{header|Perl}}==
{{trans|Python}}
<langsyntaxhighlight lang=perl>use 5.010;
use strict;
use warnings;
Line 2,494:
 
sleep(0.1);
}</langsyntaxhighlight>
===Alternate with both read and write queuing===
<langsyntaxhighlight lang=perl>#!/usr/bin/perl
 
use strict; # http://www.rosettacode.org/wiki/Chat_server
Line 2,575:
}
}
}</langsyntaxhighlight>
 
=={{header|Phix}}==
===server===
<!--<langsyntaxhighlight lang=Phix>(notonline)-->
<span style="color: #000080;font-style:italic;">--
-- demo\rosetta\ChatServer.exw
Line 2,749:
<span style="color: #7060A8;">IupMainLoop</span><span style="color: #0000FF;">()</span>
<span style="color: #7060A8;">IupClose</span><span style="color: #0000FF;">()</span>
<!--</langsyntaxhighlight>-->
===client===
<!--<langsyntaxhighlight lang=Phix>(notonline)-->
<span style="color: #000080;font-style:italic;">--
-- demo\rosetta\ChatClient.exw
Line 2,993:
<span style="color: #7060A8;">IupMainLoop</span><span style="color: #0000FF;">()</span>
<span style="color: #7060A8;">IupClose</span><span style="color: #0000FF;">()</span>
<!--</langsyntaxhighlight>-->
 
=={{header|PicoLisp}}==
<langsyntaxhighlight lang=PicoLisp>#!/usr/bin/picolisp /usr/lib/picolisp/lib.l
 
(de chat Lst
Line 3,023:
(tell 'chat "--- " *Name " left ---")
(bye) ) ) )
(wait)</langsyntaxhighlight>
After starting the above script, connect to the chat server from two terminals:
<pre> Terminal 1 | Terminal 2
Line 3,060:
 
This version will load the server automatically on port 5000, adapt to your needs.
<langsyntaxhighlight lang=prolog>:- initialization chat_server(5000).
 
chat_server(Port) :-
Line 3,140:
msg_username_taken('That username is already taken, choose another\n\r').
msg_new_line('\n\r').
msg_by_user('~w> ~w').</langsyntaxhighlight>
 
=={{header|Python}}==
<langsyntaxhighlight lang=python>#!/usr/bin/env python
 
import socket
Line 3,220:
time.sleep(.1)
except (SystemExit, KeyboardInterrupt):
break</langsyntaxhighlight>
 
=={{header|R}}==
This implementation relies on the new server socket connection type introduced in R 4.0.0.
<syntaxhighlight lang=R>
<lang R>
chat_loop <- function(server, sockets, delay = 0.5) {
repeat {
Line 3,370:
}
 
start_chat_server()</langsyntaxhighlight>
 
=={{header|Racket}}==
Line 3,376:
This is a very basic chat server, but it does everything that is needed for this task.
 
<langsyntaxhighlight lang=racket>
#lang racket
 
Line 3,398:
(void (thread (λ() (chat-server (tcp-listen 12321)))))
((client (current-input-port) (current-output-port)))
</syntaxhighlight>
</lang>
 
=={{header|Raku}}==
Line 3,405:
<div style="display:inline-block">{{trans|Python}}</div> (or at least started out that way)
{{works with|Rakudo|2016.07}}
<syntaxhighlight lang=raku perl6line>react {
my %connections;
Line 3,447:
}
}
}</langsyntaxhighlight>
 
Notes:
Line 3,455:
 
=={{header|Ruby}}==
<langsyntaxhighlight lang=Ruby>require 'gserver'
 
class ChatServer < GServer
Line 3,523:
#Turn on informational messages
ChatServer.new(7000, '0.0.0.0', 100, $stderr, true).start.join
</syntaxhighlight>
</lang>
 
=={{header|Rust}}==
<langsyntaxhighlight lang=rust>
use std::collections::HashMap;
use std::io;
Line 3,623:
chat_loop(&listener).unwrap();
}
</syntaxhighlight>
</lang>
 
=={{header|Tcl}}==
{{works with|Tcl|8.6}}
<langsyntaxhighlight lang=tcl>package require Tcl 8.6
 
# Write a message to everyone except the sender of the message
Line 3,687:
socket -server {coroutine c[incr count] chat} 4004
set ::cmap {}; # Dictionary mapping nicks to channels
vwait forever; # Run event loop</langsyntaxhighlight>
 
=={{header|Visual Basic .NET}}==
{{trans|C#}}
<langsyntaxhighlight lang=vbnet>Imports System.Net.Sockets
Imports System.Text
Imports System.Threading
Line 3,824:
End Sub
 
End Module</langsyntaxhighlight>
 
=={{header|Wren}}==
Line 3,832:
 
As Wren's VM is single threaded we create separate VMs to service each potential client connection (limited to 10) which run in their own thread. As the only way for the VMs to share mutable state is to use global variables within the host, synchronization is needed when accessing such variables.
<langsyntaxhighlight lang=ecmascript>/* chat_server.wren */
 
class Clients {
Line 4,030:
foreign static read(connfd, count)
foreign static close(connfd)
}</langsyntaxhighlight>
<br>
We now embed this in the following C program, build and run it to start the server. To end the server, just press control-C. For testing purposes, clients can use telnet from separate terminals to connect to the server on port 5000.
<langsyntaxhighlight lang=c>/* gcc chat_server.c -o chat_server -lpthread -lwren -lm */
 
#include <sys/socket.h>
Line 4,385:
 
return 0;
}</langsyntaxhighlight>
 
=={{header|zkl}}==
{{trans|Python}}
On my Linux box, telnet seems to only want to connect to port 23.
<langsyntaxhighlight lang=zkl>const PORT=23;
var users=Dictionary(); // ( handle:socket, ...)
Line 4,438:
server:=Network.TCPServerSocket.open(PORT);
println("Listening on %s:%s".fmt(server.hostname,server.port));
server.listen(pipe); // Main event loop </langsyntaxhighlight>
{{out}}
Start the server:
10,333

edits