HTTP Chat sample (.NET)
Overview
The HTTP Chat Sample
demonstrates how to use callback events through the HTTP Channel to create an HTTP-based chat program. The client polls for new messages every few seconds and the server distributes the messages to the appropriate client(s). To demonstrate all implemented features, you need to run at least three clients.
Getting started
- Compile the entire solution.
- Run the server application.
- Run two or more client applications.
- Log in in all clients using different names.
- Test sending and receiving messages.
- Change the message on the server and client sides and test again.
- Test the
Warn shutdown
server function. - Test the
Kick user
server function.
Examine the code
The Server
- Open
HTTPChatLibrary
in the Service Builder in Solution Explorer to see its service and some events under the two EventSync elements. - Examine the
HTTPChatService
service implementation (ChatService_Impl
file):
public virtual String Login(String userId)
{
var lLoginname = userId.ToUpper();
if (fUsersList.ContainsKey(lLoginname))
{
DestroySession();
throw new Exception(String.Format("User {0} already logged in!", userId));
}
var lUserInfo = new TUserInfo();
lUserInfo.UserID = userId;
lUserInfo.SessionID = SessionID.ToString();
String lRes = String.Concat("{", lUserInfo.SessionID, "}");
lock (this)
{
fUsersList.Add(lLoginname, lUserInfo);
UserID = lLoginname;
}
SubscribeClientEventSink(typeof(IHTTPChatEvents));
SubscribeClientEventSink(typeof(IHTTPChatServerEvents));
ChatEvents.OnLogin(lUserInfo);
return lRes;
}
public virtual void Logout()
{
ChatEvents.OnLogout(UserID);
lock (this)
{
fUsersList.Remove(UserID);
}
UnsubscribeClientEventSink(typeof(IHTTPChatEvents));
UnsubscribeClientEventSink(typeof(IHTTPChatServerEvents));
DestroySession();
}
- Note that the
SubscribeClientEventSink
andUnsubscribeClientEventSink
functions are called. These functions subscribe and unsubscribe the current client to and from the event sink. - Examine how messages are sent to clients:
public virtual void SendMessage(String message, String destination)
{
if (String.IsNullOrEmpty(destination))
{
ChatEvents.OnSendMessage(UserID, message, false);
return;
}
String[] lSessions = destination.Split(new Char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
if (lSessions.Length == 0)
return;
Guid[] lSessionIds = new Guid[lSessions.Length];
for (Int32 i = 0; i < lSessions.Length; i++)
lSessionIds[i] = new Guid(lSessions[i]);
IHTTPChatEvents lEventSink = (IHTTPChatEvents)GetEventSink(typeof(IHTTPChatEvents), lSessionIds);
lEventSink.OnSendMessage(this.UserID, message, true);
}
- Examine how events can be called on clients from the server (
Main.cs
file). Notice that these events are initiated from outside the service code:
private void btKick_Click(object sender, EventArgs e)
{
if (lbSessions.SelectedIndex >= 0)
{
var lSess = (Guid)lbSessions.SelectedItem;
var lEv = (IHTTPChatServerEvents)eventSinkManager.GetEventSink(lSess, typeof(IHTTPChatServerEvents));
lEv.OnMandatoryClose(String.Concat("{", lSess.ToString(), "}"), "You've been kicked from the chat!");
}
else
{
MessageBox.Show("Please select a user session to kick");
}
}
private void btWarn_Click(object sender, EventArgs e)
{
var lEv = (IHTTPChatServerEvents)eventSinkManager.GetEventSink(Guid.Empty, typeof(IHTTPChatServerEvents));
if (lEv != null) lEv.OnSystemShutdown(5, "Administrative server shutdown warning");
}
The Client
- Examine the
Form1
class. Notice that this class supports the IHTTPChatEvents and IHTTPChatServerEvents interfaces that allow it to be the event handler:
public class Form1 : System.Windows.Forms.Form, IHTTPChatEvents, IHTTPChatServerEvents
- The
eventReceiver
field ofRemObjects.SDK.EventReceiver
type is responsible for receiving and dispatching events. It is necessary to call theRegisterEventHandler
method to start receiving events and dispatch them to the appropriate handler:
eventReceiver.RegisterEventHandler(this);
JavaScript clients
Open http://localhost:8099/js/ when the HTTP chat server is running (JSON message only). Examine the page source to see the EventReceiver
usage example.