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 and UnsubscribeClientEventSink 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 of RemObjects.SDK.EventReceiver type is responsible for receiving and dispatching events. It is necessary to call the RegisterEventHandler 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.