如何使用XSockets中的C#客户端API获取/设置属性

时间:2014-05-17 23:56:44

标签: c# xsockets.net

在XSockets Server API中有一个示例,说明如何使用JavaScript API

在服务器控制器上获取/设置属性
  

从客户端APITop获取/设置属性

     

如果您拥有拥有公共getter或setter的属性,则可以访问   来自客户端API的getter / setter方法

public string MyProp {get;set;}
     

可以从客户端API检索和更改上面的属性   (JavaScript和C#)。有关如何设置新值的示例   的JavaScript

conn.publish('set_MyProp',{value:'NewValue'});
     

有关详细信息,请参阅客户端API。

Client API's page

上没有任何信息

我很难搞清楚JavaScript代码的等效C#客户端代码conn.publish('set_MyProp',{value:'NewValue'});

非常感谢任何帮助。

2 个答案:

答案 0 :(得分:3)

好吧,通过试错,我发现了一个很难的方法:

Client.Send(new { value = "NewValue" }, "set_MyProp");

等效代码是否为:

conn.publish('set_MyProp',{value:'NewValue'});

注意“价值”的情况!!!不要把这个词大写!

<强>更新

我已经创建了两个扩展方法,这使得获取和设置属性值非常容易(还有一个WaitForConnection,这在某些同步场景中非常有用,例如单元测试。

由于XSockets(非常不幸)不是开源的,文档很少,我不得不猜测事情是如何工作的,所以我的扩展方法可能不像我能够阅读源代码那样高效和优雅代码,我可能对我从服务器读取属性的方法过于“谨慎”......如果有人知道如何改进它,请编辑答案或在评论部分建议:

public static class XSocketClientExtensions
{
    public static bool WaitForConnection(this XSocketClient client, int timeout=-1) {
        return SpinWait.SpinUntil(() => client.IsConnected, timeout);
    }

    public static void SetServerProperty(this XSocketClient client, string propertyName, object value) {
        client.Send(new { value = value }, "set_" + propertyName);
    }

    public static string GetServerProperty(this XSocketClient client, string propertyName) {
        var bindingName = "get_" + propertyName;
        // why event name is lowercase? 
        var eventName = bindingName.ToLowerInvariant();
        // we must be careful to preserve any existing binding on the server property
        var currentBinding = client.GetBindings().FirstOrDefault(b => b.Event == eventName);
        try {
            // only one binding at a time per event in the client
            if (currentBinding != null)
                client.UnBind(bindingName);
            var waitEvent = new ManualResetEventSlim();
            string value = null;
            try {
                client.Bind(bindingName, (e) => {
                    value = e.data;
                    waitEvent.Set();
                });
                // we must "Trigger" the reading of the property thru its "event" (get_XXX)
                client.Trigger(bindingName);
                // and wait for it to arrive in the callback
                if (waitEvent.Wait(5000))
                    return value;
                throw new Exception("Timeout getting property from XSockets controller at " + client.Url);
            } finally {
                client.UnBind(bindingName);
            }
        } finally {
            // if there was a binding already on the "property getter", we must add it back
            if (currentBinding != null) 
                client.Bind(bindingName, currentBinding.Callback);
        }
    }
}

用法轻而易举:

// Custom controller
public class MyController : XSocketController
{
    public int Age { get; set; }

    public override void OnMessage(ITextArgs textArgs) {
        this.SendToAll(textArgs);
    }
}

// then in the client
var client = new XSocketClientEx("ws://127.0.0.1:4502/MyController", "*");
client.WaitForConnection(); // waits efficiently for client.IsConnected == true
client.SetServerProperty("Age", 15);
int age = Convert.ToInt32(client.GetServerProperty("Age"));

你可以跳过以下内容,这只是一个咆哮!

有些事情使得从一开始就难以确定下来。 JavaScript客户端和C#客户端之间没有协议。所以你在其中学到的东西并没有转化为其他技术。在我自己的多语言客户端API上,我尝试使所有API都表现得非常相似,如果不相同,那么代码几乎是可移植的。我有一个在JavaScript,C#和Java中看起来几乎相同的API。

困扰我的差异是:

  1. 这些方法有不同的名称:JavaScript中的publish与C#
  2. 中的Send
  3. 参数以相反的顺序传递:C#中的value, event,JavaScript中的event, value
  4. 本身没有区别,但是如果你在C#示例中使用'Value'它将不起作用,你必须使用'value'...我不相信它应该区分大小写。 .. 这个推理很有说服力。那我就放弃了!

答案 1 :(得分:2)

我同意,JavaScript和C#之间的API应该更相似。从4.0开始,它们都支持pub / sub和rpc,并且在接口上具有相同的命名。

设置/获取属性将有一些方法可以帮助您,因为例如设置Enums和Strings会有所不同。所以API会有类似的方法.. (请注意,您将在1个连接上复用n个控制器,这就是指定控制器名称的原因)

C#

conn.Controller("NameOfController").SetEnum("name", "value");
conn.Controller("NameOfController").SetProperty("name", object);

的JavaScript

conn.nameofcontroller.setEnum('name', 'value');
conn.nameofcontroller.setProperty('name', object);

如果你把C#中的“value”参数大写,那么关于错误... 由于我们使用编译器为公共getter和setter创建的方法值实际上是方法的参数,因此不应该大写。