We have now reached the point where we are ready to bring Socket.IO into our server and create a running server implementation. Run the following command to incorporate Socket.IO and the related DefinitelyTyped definitions:
npm install --save socket.io @types/socket.io
With these definitions available to us, we are going to bring Socket.IO support into our server and begin running it, ready to receive and transmit messages:
export class SocketServer {
public Start() {
const appSocket = socket(3000);
this.OnConnect(appSocket);
}
private OnConnect(io: socket.Server) {
}
}
new SocketServer.Start();
The parameter that our OnConnect method receives is the starting point for receiving and reacting to messages in Socket.IO. We use this to listen for a connection message that will indicate that a client has connected. When the client connects, it opens up what amounts to a socket for us on which to start receiving and sending messages. When we want to send messages directly to a particular client, we will use methods available from the socket that's returned in the following code snippet:
io.on('connection', (socket:any) => {
});
One of the things we want to provide for our clients is a history of the conversations that have gone on beforehand. This means that we want to read and save our messages to the database. Inside our connection, we are going to read all of the messages for the room the user is currently in and return them to the user. If a user has not logged in, they will only be able to see messages where the room has not been set:
this.messageDataAccess.GetAll({room: room}, {messageText: 1, _id: 0}).then((msgs: string[]) =>{
socket.emit('allMessages', msgs);
});
The syntax looks slightly strange, so we will break it down step by step. The call to GetAll is calling the general-purpose GetAll method from our DataAccessBase class. When we created that implementation, we discussed the need to make it more general purpose, and to allow the calling code to specify what fields to filter on as well as what fields to return. When we say {room: room}, we are telling Mongo that we want to filter our results based on the room. We can think of the equivalent SQL clause as being WHERE room = roomVariable. We also want to indicate what results we want back; in this case, we only want messageText without the _id field, so we use the {messageText: 1, _id: 0} syntax. When the results come back, we need to send the array of messages over to the client using socket.emit. This command sends these messages to the client that opened the connection, using allMessages as the key. If the client has code to receive allMessages, it will be able to react to these messages.
There isn't much point creating the server and sending messages if we haven't got anything at the client end to receive them. Even though we don't have all of our messages in place yet, we have sufficient infrastructure in place to start writing our client.