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

本文关键字:API 客户端 获取 属性 设置 XSockets | 更新日期: 2023-09-27 18:03:56

在XSockets服务器API中有一个关于如何使用JavaScript API获取/设置服务器控制器属性的示例

从客户端获取/设置属性

如果你有一个可以访问的带有公共getter或setter的属性客户端API的

中的getter/setter方法
public string MyProp {get;set;}

上面的属性可以从客户端API中检索和更改(包括JavaScript和c#)。设置新值的示例JavaScript

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

查看客户端API获取更多信息。

但是客户端API页面上没有任何信息

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

任何帮助都非常感激。

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

通过试错,我发现了这个困难的方法:

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

相当于:

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

注意value的大小写!!不要把这个词大写!

我已经创建了两个扩展方法,这使得它很容易获得和设置属性值(也有一个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的行为和外观非常相似,如果不是完全相同的话,所以代码几乎是可移植的。我有一个API,看起来几乎相同的JavaScript, c#和Java。

困扰我的差异是:

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

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

属性的设置/获取将有方法来帮助你,因为设置枚举和字符串是有区别的。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创建的方法,value实际上是方法的参数,不应该大写。