- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我最近在尝试使用 SendAsync 方法广播到打开的 WebSocket 时遇到问题,收到 InvalidOperationException 消息“发送操作已经在进行中”
深入挖掘 WebSocket 类的源代码,在内部跟踪忙碌状态:
internal ChannelState _sendState;
// Represents the state of a single channel; send and receive have their own states
internal enum ChannelState {
Ready, // this channel is available for transmitting new frames
Busy, // the channel is already busy transmitting frames
Closed // this channel has been closed
}
理想情况下,如果我要向 WebSocket 连接广播更新,我想提前知道它正忙并执行一些其他处理(例如将消息排队)。
这个状态被标记为内部状态似乎很奇怪——如果它是我可以简单检查的公共(public)属性(property)
context.WebSocket.SendState == ChannelState.Ready
WebSocket 上 SendAsync 的正确模式是什么可以防止抛出此异常?
我不愿意通过反射破解对该属性的访问。
编辑澄清:
WebSocket.State 属性对这种情况无济于事。该属性使用此枚举:
public enum WebSocketState
{
None,
Connecting,
Open,
CloseSent,
CloseReceived,
Closed,
Aborted
}
一旦套接字连接打开,无论它是否正忙于发送,该语句都将评估为“真”:
context.WebSocket.State == WebSocketState.Open
最佳答案
我已经实现了一个似乎可以满足我的需求的解决方案。
基本问题是当两个线程试图在同一个 WebSocket 上发送时。
我的解决方案有几个部分,并且取决于它在 AspNetWebSocketContect 下运行这一事实,因此我可以使用“Items”字典来存储有关当前连接的属性。
这是我目前在开发环境中使用的代码——我会监控它的扩展性:
/// <summary>
/// Send a message to a specific client.
/// </summary>
/// <param name="context"></param>
/// <param name="buffer"></param>
/// <returns></returns>
private static async Task SendMessage(AspNetWebSocketContext context, ArraySegment<byte> buffer)
{
// Return control to the calling method immediately.
await Task.Yield();
// Make sure we have data.
if (buffer.Count == 0)
return;
// The state of the connection is contained in the context Items dictionary.
bool sending;
lock (context)
{
// Are we already in the middle of a send?
bool.TryParse(context.Items["sending"]?.ToString(), out sending);
// If not, we are now.
if (!sending)
context.Items["sending"] = true;
}
if (!sending)
{
// Lock with a timeout, just in case.
if (!Monitor.TryEnter(context.WebSocket, 1000))
{
// If we couldn't obtain exclusive access to the socket in one second, something is wrong.
await context.WebSocket.CloseAsync(WebSocketCloseStatus.InternalServerError, string.Empty, CancellationToken.None);
return;
}
try
{
// Send the message synchronously.
var t = context.WebSocket.SendAsync(buffer, WebSocketMessageType.Text, true, CancellationToken.None);
t.Wait();
}
finally
{
Monitor.Exit(context.WebSocket);
}
// Note that we've finished sending.
lock (context)
{
context.Items["sending"] = false;
}
// Handle any queued messages.
await HandleQueue(context);
}
else
{
// Add the message to the queue.
lock (context)
{
var queue = context.Items["queue"] as List<ArraySegment<byte>>;
if (queue == null)
context.Items["queue"] = queue = new List<ArraySegment<byte>>();
queue.Add(buffer);
}
}
}
/// <summary>
/// If there was a message in the queue for this particular web socket connection, send it.
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
private static async Task HandleQueue(AspNetWebSocketContext context)
{
var buffer = new ArraySegment<byte>();
lock (context)
{
// Check for an item in the queue.
var queue = context.Items["queue"] as List<ArraySegment<byte>>;
if (queue != null && queue.Count > 0)
{
// Pull it off the top.
buffer = queue[0];
queue.RemoveAt(0);
}
}
// Send that message.
if (buffer.Count > 0)
await SendMessage(context, buffer);
}
我对这种方法的一些考虑:
关于c# - 检测到 "Busy"WebSocket,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36877030/
我知道使用 https://www.skype.com/en/developer/create-contactme-buttons/ 添加 Skype 链接很容易.但是可以为 SkypeForBusi
Closed. This question is opinion-based。它当前不接受答案。 想改善这个问题吗?更新问题,以便editing this post用事实和引用来回答。 上个月关闭。
Closed. This question is off-topic。它当前不接受答案。 想改善这个问题吗? Update the question,所以它是用于堆栈溢出的on-topic。 已关闭8
我们使用一个持久的 Skype for Business 聊天室,并用它来广播每天在特定项目上完成的工作。我想在每个工作日早上启动 Skype for Business 并将其打开到这个聊天室。我想使
我在本地和远程(通过 VPN)与 GUI 应用程序交互。当我在本地使用它时,大多数操作发生得非常快,而且我的 sikuli 脚本执行得很好。但是,当我远程使用它时,操作需要更长的时间才能完成。 也就是
如何在业务催化剂中编辑模板?我可以从用户界面执行此操作还是需要 Dreamweaver 或其他一些产品? 我用谷歌搜索,但找不到答案...... 当我登录时,在网站选项卡下,有站点编辑器、网页、博客和
我刚开始使用 Google My Business API,并且能够执行获取操作只是为了验证我的 Oauth 设置是否正确。现在我想使用 GMB 添加位置 API 的 post 方法添加一个位置,但在
我们在我们的应用程序中使用 Skype for Business Web SDK 来显示联系人的存在。 当联系人是用户组织内部的某个人(因此与用户在同一个 AD 实例)时,我们在联系人的状态 onCh
有没有办法使用 GMB API 获取评论的链接? 最接近我需要的是这个: https://www.google.com/maps/contrib/113400145807499011881/place
{ "error": { "code": 429, "message": "Quota exceeded for quota metric'Requests' and limit 'Requests
有很多为 Skype 创建 HTML 链接的解决方案(href="skype:username"),但我找不到任何适用于 Skype for Business 的解决方案。 (引用=“啜饮: 有关如何
对于给定的 n 态 busy beaver game , 是 busy beaver function是唯一的,还是可能有多个功能具有相同的最高分?也许这两种方式都没有得到证明? 最佳答案 是的,是的
也许我在当前的 Google MyBusiness API 迁移中遗漏了一些东西。 我们有在 Google My Business API 上运行的脚本,该 API 将于 2022 年 4 月结束,取
在 Business Objects XI Web Intelligence 中,Rank 函数返回密集结果。例如,当按“金额”排名时,我只想返回前十名记录。然而,三项记录在“金额”上并列第五。结果总
我正在按照本指南 ( https://msdn.microsoft.com/en-us/skype/ucwa/authenticationusingazuread ) 尝试和验证并创建 Skype 应
由于我一直在努力学习 Angular,所以这几天我一直在与这个 ng-busy 作斗争。 我有一个 plunker 页面,它可以工作,但不是我想要的。该页面正在显示加载动画,但我想让它在按钮内显示加载
我正在运行关于 svn 的 java 代码,它是这样的 http://code.google.com/p/justcodingforfun/source/browse/MagicMissile/src
请帮助我理解。我是一名技术专家,并试图确定在使用WhatsApp Cloud API执行分配给我的业务任务时是否会有任何限制。。在WhatsApp Business Account文档中,我看到了许多
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 9
我正在尝试为我的大型 ASP.NET MVC 应用程序创建业务和数据层。因为这是我第一次尝试这种规模的项目,所以我正在阅读一些书籍,并努力小心地将事情正确地分开。通常我的应用程序混合了业务逻辑和数据访
我是一名优秀的程序员,十分优秀!