Xamarin Mono ClientWebSocket injection does not work for secure sockets

I'm having trouble implementing a secure Osx web socket client. I am using ClientWebSocket from System.Net.WebSockets. Here are some test codes:

static async Task RunLoop() { ClientWebSocket ws = new ClientWebSocket(); await ws.ConnectAsync(new Uri("wss://echo.websocket.org"), CancellationToken.None); do { Console.Write("Enter message:"); var msg = Console.ReadLine(); if (msg == "quit") { break; } var b = new ArraySegment<byte>(UTF8Encoding.UTF8.GetBytes(msg)); await ws.SendAsync(b, WebSocketMessageType.Text, true, CancellationToken.None); byte[] bb = new byte[2048]; ArraySegment<byte> buffer = new ArraySegment<byte>(bb); var result = await ws.ReceiveAsync(buffer, CancellationToken.None); switch (result.MessageType) { case WebSocketMessageType.Text: Console.WriteLine(UTF8Encoding.UTF8.GetString(buffer.Array)); break; case WebSocketMessageType.Close: await ws.CloseAsync(WebSocketCloseStatus.NormalClosure, "", CancellationToken.None); break; } } while (true); } static void Main(string[] args) { var task = RunLoop(); task.Wait(); } 

Every time I got this exception when ReceiveAsync is called.

 Cannot access a disposed object. 

Object Name: 'System.Net.Sockets.NetworkStream'.

  at System.Net.WebConnection.Read (System.Net.HttpWebRequest request, System.Byte[] buffer, System.Int32 offset, System.Int32 size) [0x0001f] in /private/tmp/source-mono-4.6.0-c8sr0/bockbuild-mono-4.6.0-branch-c8sr0/profiles/mono-mac-xamarin/build-root/mono-x86/mcs/class/System/System.Net/WebConnection.cs:1038 at System.Net.WebSockets.ClientWebSocket+<ReceiveAsync>c__AnonStorey5.<>m__0 () [0x0017c] in /private/tmp/source-mono-4.6.0-c8sr0/bockbuild-mono-4.6.0-branch-c8sr0/profiles/mono-mac-xamarin/build-root/mono-x86/mcs/class/System/System.Net.WebSockets/ClientWebSocket.cs:259 at System.Threading.Tasks.Task`1[TResult].InnerInvoke () [0x00012] in /private/tmp/source-mono-4.6.0-c8sr0/bockbuild-mono-4.6.0-branch-c8sr0/profiles/mono-mac-xamarin/build-root/mono-x86/mcs/class/referencesource/mscorlib/system/threading/Tasks/Future.cs:680 at System.Threading.Tasks.Task.Execute () [0x00016] in /private/tmp/source-mono-4.6.0-c8sr0/bockbuild-mono-4.6.0-branch-c8sr0/profiles/mono-mac-xamarin/build-root/mono-x86/mcs/class/referencesource/mscorlib/system/threading/Tasks/Task.cs:2502 --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in /private/tmp/source-mono-4.6.0-c8sr0/bockbuild-mono-4.6.0-branch-c8sr0/profiles/mono-mac-xamarin/build-root/mono-x86/mcs/class/referencesource/mscorlib/system/runtime/exceptionservices/exceptionservicescommon.cs:143 at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x00047] in /private/tmp/source-mono-4.6.0-c8sr0/bockbuild-mono-4.6.0-branch-c8sr0/profiles/mono-mac-xamarin/build-root/mono-x86/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:187 at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x0002e] in /private/tmp/source-mono-4.6.0-c8sr0/bockbuild-mono-4.6.0-branch-c8sr0/profiles/mono-mac-xamarin/build-root/mono-x86/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:156 at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x0000b] in /private/tmp/source-mono-4.6.0-c8sr0/bockbuild-mono-4.6.0-branch-c8sr0/profiles/mono-mac-xamarin/build-root/mono-x86/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:128 at System.Runtime.CompilerServices.TaskAwaiter`1[TResult].GetResult () [0x00000] in /private/tmp/source-mono-4.6.0-c8sr0/bockbuild-mono-4.6.0-branch-c8sr0/profiles/mono-mac-xamarin/build-root/mono-x86/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:357 at Test.MainClass+<RunLoop>c__async2.MoveNext () [0x001c0] in Program.cs:81 

It seems that the socket is somehow being removed, but I have no idea why and where. The same code is great for unsafe websites ("ws: //echo.websocket.org").

I also tried the WebSocket.Portable implementation, but had almost the same problems. For unsafe websites, it worked fine, but for secure websites, the OnMessage event was never raised. https://github.com/NVentimiglia/WebSocket.Portable

+5
source share
1 answer

I have found a workaround for this problem. I used SocketRocker , which is an implementation of Objective C. Square.SocketRocket is the Xamarin shell for the Objective-C native library. On GitHub you will also find several examples in the examples directory.

0
source

Source: https://habr.com/ru/post/1258931/


All Articles