Richie 的个人资料The Sandpit - "We hack s...日志列表 工具 帮助
4月9日

Geochat for Silverlight

The Prototype Lab at ESRI has just launched a geo-collaboration control for Silverlight.  The control allows users to chat and exchange information such as graphics.  Here is a live sample.

Geochat for Silverlight

Geochat is implemented in two parts.

  1. Server-side
    A Windows Communication Foundation (WCF) duplex service is created to maintain a connection to Silverlight clients.  The geochat implementation acts as broker between Silverlight clients by forwarding messages to individual (or all) clients.
    http://msdn.microsoft.com/en-us/library/cc645027(VS.95).aspx
  2. Client-side
    The Silverlight client is using PollingDuplexHttpBinding to maintain a connection with the server using AJAX polling.  The polling occurs every ten seconds.
    http://msdn.microsoft.com/en-us/library/cc645028(VS.95).aspx

The client/server implementation effectively allows the server to push information to the browser.  This is also referred to as Comet.  Source code to both of the client and server projects are provided in the download from the ESRI code gallery.

Building the Server

Compiling and publishing the WCF service is straight forward.  The only prerequisite is Microsoft .NET 3.5 SP1.  If you are publishing the service on Microsoft Windows Vista then you may need to register the “svc” MIME type using the following command.

C:\Windows\Microsoft.NET\Framework\v3.0\Windows Communication Foundation>ServiceModelReg.exe –i

Building the Client

The code gallery only includes the source code to the geochat user control rather than the entire web application.  After adding a reference to the geochat assembly, the steps below will discuss how to configure it and send/receive messages.

At the top of your code page add a using statement for the geochat namespace.

using ESRI.ArcGIS.Chat;

In the your page (or user control) constructor use the ChatEnvironment singleton to set the name of the geochat service and begin listening to incoming messages.

public Page() {
    InitializeComponent();

    // Url to the geochat service ("service.svc" will be automatically appended)
    ChatEnvironment.Default.Server = "http://your.server.com/ChatService";

    // Add event handler to listen for incoming messages
    ChatEnvironment.Default.NoteReceived += new EventHandler<NoteEventArgs>(this.ChatEnvironment_NoteReceived);
}

In the snippet below, geometry is converted to JSON and sent to all other Silverlight clients.

if (ChatEnvironment.Default.IsConnected) {
    // Create data message and assign geometry
    DataMessage dataMessage = new DataMessage() {
        Text = this.GeometryToJson(new MapPoint(10,10)),
        Type = typeof(MapPoint).ToString()
    };

    // Send data message to all silverlight clients
    ChatEnvironment.Default.SendMessage(dataMessage, null);
}

To send the message to an individual user rather than everyone, replace “null” with a user object.  Use the following property to return a collection of all available users.

ChatEnvironment.Default.Users

The snippet above referenced a method to convert ESRI’s Silverlight geometry into JSON.  Since the message will be ultimately sent down the wire as a SOAP 1.1 message, the JSON string must be enclosed in a CDATA block.

private string GeometryToJson(Geometry geometry) {
    MemoryStream memoryStream = new MemoryStream();
    DataContractJsonSerializer serializer = new DataContractJsonSerializer(geometry.GetType());
    serializer.WriteObject(memoryStream, geometry);
    memoryStream.Position = 0;
    StreamReader streamReader = new StreamReader(memoryStream);
    string json = streamReader.ReadToEnd();
    memoryStream.Close();
    return string.Format("CDATA[{0}]", json);
}

Now, let’s add code to receive incoming geometry messages.  Firstly we only want to process DataMessages and ignore other messages types (eg connection, disconnection and text).  The snippet below extracts the geometry from the message as well as the name of the sender.

private void ChatEnvironment_NoteReceived(object sender, NoteEventArgs e) {
    if (e.Note.Payload.GetType() == typeof(DataMessage)) {
        // Get DataMessage
        DataMessage dataMessage = (DataMessage)e.Note.Payload;

        // Get Geometry
        Geometry geometry = this.JsonToGeometry(dataMessage.Text, dataMessage.Type);

        // Who sent this message?
        string from = e.Note.From.FriendlyName;
    }
}

Here is the code for the JsonToGeometry method referenced above.  The code assumes that the incoming message is some sort of ESRI Silverlight geometry and that the JSON string is enclosed in a CDATA block.

private Geometry JsonToGeometry(string json, string type) {
    Type t = null;
    if (type == typeof(MapPoint).ToString()) { t = typeof(MapPoint); }
    else if (type == typeof(Polyline).ToString()) { t = typeof(Polyline); }
    else if (type == typeof(Envelope).ToString()) { t = typeof(Envelope); }
    else if (type == typeof(Polygon).ToString()) { t = typeof(Polygon); }
    else { return null; }

    // JSON to Geometry
    string json2 = json.Substring(6, json.Length - 7);
    Byte[] bytes = Encoding.Unicode.GetBytes(json2);
    MemoryStream memoryStream = new MemoryStream(bytes);
    DataContractJsonSerializer dataContractJsonSerializer = new DataContractJsonSerializer(t);
    Geometry geometry = dataContractJsonSerializer.ReadObject(memoryStream) as Geometry;
    memoryStream.Close();
    return geometry;
}

That concludes the introduction to the geochat user control for Silverlight.  Enjoy!

评论

请稍候...
很抱歉,您输入的评论太长。请缩短您的评论。
您没有输入任何内容,请重试。
很抱歉,我们当前无法添加您的评论。请稍后重试。
若要添加评论,需要您的家长授予您相应权限。请求权限
您的家长禁用了评论功能。
很抱歉,我们当前无法删除您的评论。请稍后重试。
您已超过了一天之内允许提供的评论数上限。请在 24 小时后重试。
因为我们的系统表明您可能在向其他用户提供垃圾评论,您的帐户已禁用了评论功能。如果您认为我们错误地禁用了您的帐户,请联系 Windows Live 支持部门
完成下面的安全检查,您提供评论的过程才能完成。
您在安全检查中键入的字符必须与图片或音频中的字符一致。
Carmichael​Richie 在此页禁用了评论功能。

引用通告

引用此项的网络日志