在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。
我很难搞清楚JavaScript代码的等效C#客户端代码conn.publish('set_MyProp',{value:'NewValue'});
非常感谢任何帮助。
答案 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。
困扰我的差异是:
publish
与C#Send
value, event
,JavaScript中的event, 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创建的方法值实际上是方法的参数,因此不应该大写。