SuperHTTP Chat sample (Delphi)

Overview

The SuperHTTP Chat sample provides Remoting SDK for Cocoa users with a server for working with the iOSSuperHttpChat sample. The Delphi version of this sample currently contains no client application. Please use other Delphi samples to see how superchannels can be used or how to write a chat application.

Getting Started

  • Just compile and run the application.

Examine the Code

  • Open the ChatServerLibrary in the ServiceBuilder in RO IDE menu to see its two services and three events under the ChatEvents element.
  • Notice that the ChatServerService is secure, the login procedure is controlled by the LoginService as described in this article .
  • Examine the Login service implementation:
procedure TLoginService.Login(const Nickname: string);
var
  ev: IChatEvents_Writer;
begin
  if ServerForm.UserExists(Nickname) then begin
    DestroySession;
    raise Exception.Create('Nickname already in use');
  end;
  Session.Values[NICKNAME_ID] := Nickname;
  RegisterEventClient(GUIDToString(Session.SessionID), EID_ChatEvents);
  ev := EventRepository as IChatEvents_Writer;
  ev.ExcludeSender := False;
  ev.UserLogin(Session.SessionID, Nickname);
end;
procedure TLoginService.Login(const Nickname: String);
var
  ev: IROEventWriter<IChatEvents>;
begin
  if ServerForm.UserExists(Nickname) then begin
    DestroySession;
    raise Exception.Create('Nickname already in use');
  end;
  Session.Values[NICKNAME_ID] := Nickname;
  RegisterEventClient(GUIDToString(Session.SessionID), 'ChatEvents');
  ev := EventRepository.GetWriter<IChatEvents>(Session.SessionID);
  ev.ExcludeSender := False;
  ev.Event.UserLogin(Nickname);
end;
  • Note that we call the RegisterEventClient function. This function subscribes the current client to the event sink passed there as a parameter.
  • See how we obtain an event proxy in order to fire events. The ExcludeSender property allows to skip sending the event to the current session:
  ev := EventRepository as IChatEvents_Writer;
  ev.ExcludeSender := False;
  ev.UserLogin(Session.SessionID, Nickname);
  ev := EventRepository.GetWriter<IChatEvents>(Session.SessionID);
  ev.ExcludeSender := False;
  ev.Event.UserLogin(Nickname);
  • Look at the implementation of the Talk and TalkPrivate functions in ChatServerService_Impl.pas. These functions only differ in that the TalkPrivate implementation first defines the recipient and then fires the event only for that client:
procedure TChatServerService.TalkPrivate(const TargetNickname: String; const Message: String);
var
  ev: IChatEvents_Writer;
begin
  if ServerForm.UserExists(TargetNickname) then begin
    ev := EventRepository as IChatEvents_Writer;
    ev.ExcludeSender := true;
    ev.ExcludeSessionList := False;
    ev.SessionList.Add(ServerForm.UserSession(TargetNickname));
    ev.Message(Session.SessionID, Session.Values[NICKNAME_ID], TargetNickname, Message);
  end;
end;

procedure TChatServerService.Talk(const Message: String);
var
  ev: IChatEvents_Writer;
begin
  ev := EventRepository as IChatEvents_Writer;
  ev.ExcludeSender := False;
  ev.Message(Session.SessionID, Session.Values[NICKNAME_ID], '', Message);
end;
procedure TChatServerService.TalkPrivate(const TargetNickname: String; const Message: String);
var
  ev: IROEventWriter<IChatEvents>;
begin
  if ServerForm.UserExists(TargetNickname) then begin
    ev := EventRepository.GetWriter<IChatEvents>(Session.SessionID);
    ev.ExcludeSender := true;
    ev.ExcludeSessionList := False;
    ev.SessionList.Add(ServerForm.UserSession(TargetNickname));
    ev.Event.Message(Session.Values[NICKNAME_ID], TargetNickname, Message);
  end;
end;

procedure TChatServerService.Talk(const Message: String);
var
  ev: IROEventWriter<IChatEvents>;
begin
  ev := EventRepository.GetWriter<IChatEvents>(Session.SessionID);
  ev.ExcludeSender := False;
  ev.Event.Message(Session.Values[NICKNAME_ID], '', Message);
end;
  • This service also contains the Ping dummy method. It is called by the client periodically to avoid session expiring. This method discovers the difference between the HTTP Channel and the Super HTTP Channel: the plain HTTP channel calls the predefined remote method periodically to poll for events and this resets the session timeout. The SuperHTTP channel does no polls and the session may expire if there is no other activity from this client.

See Also