Skip to content

Instantly share code, notes, and snippets.

@atsushieno
Created September 20, 2009 03:42
Show Gist options
  • Save atsushieno/189700 to your computer and use it in GitHub Desktop.
Save atsushieno/189700 to your computer and use it in GitHub Desktop.
// OK WCF sucks with REST. I dump it away.
using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;
using System.ServiceModel.Web;
namespace Slingr
{
public class Test
{
public static void Main ()
{
var c = new LingrClient ();
c.CreateAnonymousSession ();
Console.WriteLine ("session created");
c.SetPresence (true);
c.Subscribe ("atsushienotest");
foreach (var room in c.GetRooms ())
Console.WriteLine (room);
c.Dispose ();
}
}
public class LingrRoom
{
public LingrRoom (string room, string session, int counter)
{
this.Room = room;
this.Session = session;
this.Counter = counter;
}
public string Room { get; set; }
public string Session { get; set; }
public int Counter { get; set; }
}
public class LingrClient : IDisposable
{
ILingrContract lingr;
class LingrContentTypeMapper : WebContentTypeMapper
{
public override WebContentFormat GetMessageFormatForContentType (string contentType)
{
return WebContentFormat.Json; // always
}
}
class LingrEndpointBehavior : IEndpointBehavior
{
public void AddBindingParameters (ServiceEndpoint se, BindingParameterCollection pl)
{
}
public void ApplyClientBehavior (ServiceEndpoint endpoint, ClientRuntime clientRuntime)
{
clientRuntime.MessageInspectors.Add (new LingrMessageInspector ());
}
public void ApplyDispatchBehavior (ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
{
}
public void Validate (ServiceEndpoint endpoint)
{
}
}
class LingrMessageInspector : IClientMessageInspector
{
public void AfterReceiveReply (ref Message reply, object correlationState)
{
}
public object BeforeSendRequest (ref Message request, IClientChannel channel)
{
var hp = (HttpRequestMessageProperty) request.Properties [HttpRequestMessageProperty.Name];
hp.Headers ["Accept"] = "*/*";
hp.Headers ["Content-Type"] = null;
hp.Headers ["User-Agent"] = "slingr/0.1";
hp.SuppressEntityBody = true;
return null;
}
}
public LingrClient ()
{
var cf = new WebChannelFactory<ILingrClient> (
new CustomBinding (
new WebMessageEncodingBindingElement () /*{ ContentTypeMapper = new LingrContentTypeMapper () }*/,
new HttpTransportBindingElement () { ManualAddressing = true }),
new Uri ("http://lingr.com"));
cf.Endpoint.Behaviors.Add (new LingrEndpointBehavior ());
lingr = cf.CreateChannel ();
Rooms = new List<LingrRoom> ();
}
public string Presence { get; private set; }
public string Session { get; private set; }
public string NickName { get; private set; }
public string PublicId { get; private set; }
public IList<LingrRoom> Rooms { get; private set; }
public void Dispose ()
{
if (lingr == null)
return;
if (Session != null)
DestroySession ();
lingr = null;
}
void CheckErrorResponse (LingrResponse res)
{
if (res.Status != "ok")
throw new LingrException (res);
}
void SetSessionStatus (SessionStatusResponse res)
{
CheckErrorResponse (res);
Session = res.Session;
Presence = res.Presence;
PublicId = res.PublicId;
NickName = res.NickName;
}
void CheckSessionExistence ()
{
if (Session == null)
throw new InvalidOperationException ("No session is established");
}
// Session API wrappers
public void CreateAnonymousSession ()
{
var res = lingr.CreateAnonymousSession ();
SetSessionStatus (res);
}
public void CreateSession (string user, string password)
{
var res = lingr.CreateSession (user, password);
SetSessionStatus (res);
}
public void DestroySession ()
{
CheckSessionExistence ();
var res = lingr.DestroySession (Session);
CheckErrorResponse (res);
Session = null;
Presence = null;
}
public void VerifySession ()
{
CheckSessionExistence ();
var res = lingr.VerifySession (Session);
SetSessionStatus (res);
}
public void SetPresence (bool online)
{
CheckSessionExistence ();
var res = lingr.SetPresence (Session, NickName, online ? "online" : "offline");
SetSessionStatus (res);
}
// Room API wrappers
public LingrRoom Subscribe (string room)
{
CheckSessionExistence ();
var res = lingr.Subscribe (Session, room);
CheckErrorResponse (res);
var lr = new LingrRoom (room, Session, (int) res.Counter);
Rooms.Add (lr);
return lr;
}
public void Unsubscribe (LingrRoom room)
{
CheckSessionExistence ();
var res = lingr.Unsubscribe (Session, room.Room);
CheckErrorResponse (res);
Rooms.Remove (room);
}
//object Show (string session, string room);
//object Say (string session, string room, string nickname, string text, string localId);
//SubscriptionStatusResponse Observe (string session, int counter);
public string [] GetRooms ()
{
CheckSessionExistence ();
var res = lingr.GetRooms (Session);
CheckErrorResponse (res);
return res.Rooms;
}
}
public class LingrException : Exception
{
public LingrException (LingrResponse source)
: base (String.Concat (source.ErrorDetail, "(error code: ", source.ErrorCode, ")"))
{
}
}
public interface ILingrClient : ILingrContract, IClientChannel
{
}
[ServiceContract]
public interface ILingrContract
{
// Session API
[OperationContract]
[WebGet (RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, UriTemplate = "/api/session/create")]
SessionStatusResponse CreateAnonymousSession ();
[OperationContract]
[WebGet (RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, UriTemplate = "/api/session/create?user={user}&password={password}")]
SessionStatusResponse CreateSession (string user, string password);
[OperationContract]
[WebGet (RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, UriTemplate = "/api/session/verify?session={session}")]
SessionStatusResponse VerifySession (string session);
[OperationContract]
[WebGet (RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, UriTemplate = "/api/session/destroy?session={session}")]
EmptyResponse DestroySession (string session);
[OperationContract]
[WebGet (RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, UriTemplate = "/api/session/set_presence?session={session}&nickname={nickname}&presence={presence}")]
SessionStatusResponse SetPresence (string session, string nickname, string presence);
// Room API
[OperationContract]
[WebGet (RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, UriTemplate = "/api/room/show?session={session}&room={room}")]
object Show (string session, string room);
[OperationContract]
[WebGet (RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, UriTemplate = "/api/room/subscribe?session={session}&room={room}")]
SubscriptionStatusResponse Subscribe (string session, string room);
[OperationContract]
[WebGet (RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, UriTemplate = "/api/room/unsubscribe?session={session}&room={room}")]
EmptyResponse Unsubscribe (string session, string room);
[OperationContract]
[WebGet (RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, UriTemplate = "/api/room/say?session={session}&room={room}&nickname={nickname}&text={text}&local_id={localId}")]
object Say (string session, string room, string nickname, string text, string localId);
// It is hosted at different location (8080), so it's not really usable within this contract.
/*
[OperationContract]
[WebGet (RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, UriTemplate = "/api/event/observe?session={session}&counter={counter}")]
SubscriptionStatusResponse Observe (string session, int counter);
*/
// User API
[OperationContract]
[WebGet (RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, UriTemplate = "/api/user/get_rooms?session={session}")]
RoomsResponse GetRooms (string session);
}
[DataContract]
public abstract class LingrResponse
{
[DataMember (Name = "status")]
public string Status { get; set; }
[DataMember (Name = "detail")]
public string ErrorDetail { get; set; }
[DataMember (Name = "code")]
public string ErrorCode { get; set; }
}
[DataContract]
public class SessionStatusResponse : LingrResponse
{
[DataMember (Name = "public_id")]
public string PublicId { get; set; }
[DataMember (Name = "session")]
public string Session { get; set; }
[DataMember (Name = "nickname")]
public string NickName { get; set; }
[DataMember (Name = "presence")]
public string Presence { get; set; }
}
[DataContract]
public class EmptyResponse : LingrResponse
{
}
[DataContract]
public class SubscriptionStatusResponse : LingrResponse
{
[DataMember (Name = "counter")]
public int Counter { get; set; }
}
[DataContract]
public class RoomsResponse : LingrResponse
{
[DataMember (Name = "rooms")]
public string [] Rooms { get; set; }
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment