Search code examples
multithreadingsocketsoopchatd

Dlang,Socket,Chat Server


I want to write a chat server. Using the programming language D. (Dlang) It is desirable to use OOP.

My example.(Not working)

import std.stdio;
import std.concurrency;
import core.thread;
import std.conv;
import std.socket;

synchronized class DataInfo{
    shared this()
    {
    }
    public shared Socket[] sockList; 
    shared void AddSocket(shared Socket scket)
    {
        sockList ~= scket; 
    }

    shared(Socket[]) getSockList()
    {
        return to!(shared Socket[])(sockList);
    }
}
void UserLoop(shared DataInfo data,shared(int) id)
{
    Socket client;
    synchronized(data)
    {
        client = cast(Socket)(data.sockList[id]);
    }

    while(true)
    {
        char[1024] buffer; 
        int sockCount = 0;
        client.receive(buffer);
        synchronized(data)
        {
            sockCount = data.sockList.length;
        }

        for(int i =0 ; i < sockCount; i++)
        {
            synchronized(data)
            {
                auto sk = cast( Socket)(data.sockList[i]);
                sk.send("Hello world");
            }
        }
    }
}

int main()
{

        ushort port;
        port = 4444;

        auto listener = new TcpSocket();
        assert(listener.isAlive);
        listener.blocking = false;
        listener.bind(new InternetAddress(port));
        listener.listen(10);
        writefln("Listening on port %d.", port);
        shared(DataInfo) data = new shared(DataInfo);
        while(true)
        {
            int len = 0;
            auto client = cast(shared Socket)listener.accept();
            synchronized(data)
            {
                data.AddSocket(client);
                len = data.sockList.length; 
            }
            spawn(&UserLoop,data,cast(shared int)len);
        }
        return 0;
}

How? How to fix the bug? Can I get an example of correct chat servers? (Only Dlang) Also, can you give an example of the correct client.


Solution

  • import vibe.d;
    import vibe.utils.array;
    
    shared static this()
    {
        Chat m_chat=new Chat();
        ushort port=5555;
        listenTCP(port,&m_chat.connHandler,"127.0.0.1");
    }
    class Chat{
    private:
            TCPConnection[] connz;
    public:
        void connHandler(TCPConnection conn){
            sendMessage(conn,"Hello!\n");
            connz~=conn;
            while(conn.connected){
                while(conn.waitForData(dur!"seconds"(1L))){
                    ubyte[1] c;
                    string inMessage;
                    while(conn.dataAvailableForRead){
                        conn.read(c);
                        inMessage~=c;
                    }
                    foreach(TCPConnection _con; connz){
                        if(_con!=conn)
                            sendMessage(_con,"Someone says: "~inMessage);
                    }
                }   
            }
            connz.removeFromArray(conn);
        }
        void sendMessage(TCPConnection conn, string message){
            conn.write(cast(ubyte[])message);
        }
    }
    

    Solution suggested by Lord_Evil