petushok55
@petushok55
Обучаюсь на практике.

Почему при взаимодействии с UI в OnMessage вебсокет закрывает соединение?

WebSocketSharp использую это
using WebSocketSharp;
using UnityEngine;
using Newtonsoft.Json;
using TMPro;

public class WS_Client : MonoBehaviour
{
    public TMP_Text response_text;
    WebSocket ws;
    void Start()
    {
        ws = new WebSocket("ws://localhost:2030");
        ws.OnOpen += (sender, e) =>
        {
            Debug.Log("Подключение к вебсокету успешно!");
        };

        ws.OnMessage += (sender, e) =>
        {
            Debug.Log("Message: " + e.Data); // сделаю дебаг, всё норм
            response_text.text = e.Data; // сделаю вот так ЗДЕСЬ и на те сокет закрывает соединение!
        };

        ws.Connect();

        ws.OnError += (sender, e) =>
        {
            ws.Close();
        };

        ws.OnClose += (sender, e) =>
        {
            ws.Close();
        };

    }
}

Почему так происходит?
debug
Вебсокет закрыт:
0x00007ff7972f930d (Unity) StackWalker::GetCurrentCallstack
0x00007ff7972fffe9 (Unity) StackWalker::ShowCallstack
0x00007ff79826d613 (Unity) GetStacktrace
0x00007ff79890223d (Unity) DebugStringToFile
0x00007ff7964647e2 (Unity) DebugLogHandler_CUSTOM_Internal_Log
0x000002f0d789cf83 (Mono JIT Code) (wrapper managed-to-native) UnityEngine.DebugLogHandler:Internal_Log (UnityEngine.LogType,UnityEngine.LogOption,string,UnityEngine.Object)
0x000002f0d789cc5b (Mono JIT Code) UnityEngine.DebugLogHandler:LogFormat (UnityEngine.LogType,UnityEngine.Object,string,object[])
0x000002f0e15709e0 (Mono JIT Code) UnityEngine.Logger:Log (UnityEngine.LogType,object)
0x000002f0e1570508 (Mono JIT Code) UnityEngine.Debug:Log (object)
0x000002f0e15ceedb (Mono JIT Code) [WS_Client.cs:55] WS_Client:b__4_3 (object,WebSocketSharp.CloseEventArgs)
0x000002f0e15b124f (Mono JIT Code) WebSocketSharp.Ext:Emit (System.EventHandler`1,object,TEventArgs_REF)
0x000002f0e15ccf33 (Mono JIT Code) WebSocketSharp.WebSocket:close (WebSocketSharp.PayloadData,bool,bool,bool)
0x000002f0e15cc7eb (Mono JIT Code) WebSocketSharp.WebSocket:close (uint16,string)
0x000002f0e15cc63b (Mono JIT Code) WebSocketSharp.WebSocket:Close ()
0x000002f0e15ca603 (Mono JIT Code) [WS_Client.cs:48] WS_Client:b__4_2 (object,WebSocketSharp.ErrorEventArgs)
0x000002f0e15b124f (Mono JIT Code) WebSocketSharp.Ext:Emit (System.EventHandler`1,object,TEventArgs_REF)
0x000002f0e15c9fdb (Mono JIT Code) WebSocketSharp.WebSocket:error (string,System.Exception)
0x000002f0e15b0f33 (Mono JIT Code) WebSocketSharp.WebSocket:messagec (WebSocketSharp.MessageEventArgs)
0x000002f0e15b0ca3 (Mono JIT Code) (wrapper runtime-invoke) :runtime_invoke_void__this___object (object,intptr,intptr,intptr)
0x00007ffab1e3e4b4 (mono-2.0-bdwgc) [mini-runtime.c:3445] mono_jit_runtime_invoke
0x00007ffab1d7e764 (mono-2.0-bdwgc) [object.c:3066] do_runtime_invoke
0x00007ffab1d857ff (mono-2.0-bdwgc) [object.c:5777] mono_runtime_try_invoke_array
0x00007ffab1d8d098 (mono-2.0-bdwgc) [object.c:8712] mono_message_invoke
0x00007ffab1d8c8be (mono-2.0-bdwgc) [object.c:8522] ves_icall_System_Runtime_Remoting_Messaging_AsyncResult_Invoke
0x00007ffab1ceba12 (mono-2.0-bdwgc) [icall-def.h:850] ves_icall_System_Runtime_Remoting_Messaging_AsyncResult_Invoke_raw
0x000002f0e15b0a23 (Mono JIT Code) (wrapper managed-to-native) System.Runtime.Remoting.Messaging.AsyncResult:Invoke (System.Runtime.Remoting.Messaging.AsyncResult)
0x000002f0e15b086b (Mono JIT Code) System.Runtime.Remoting.Messaging.AsyncResult:System.Threading.IThreadPoolWorkItem.ExecuteWorkItem ()
0x000002f0d781122a (Mono JIT Code) System.Threading.ThreadPoolWorkQueue:Dispatch ()
0x000002f0d78107ab (Mono JIT Code) System.Threading._ThreadPoolWaitCallback:PerformWaitCallback ()
0x000002f0d7810885 (Mono JIT Code) (wrapper runtime-invoke) :runtime_invoke_bool (object,intptr,intptr,intptr)
0x00007ffab1e3e4b4 (mono-2.0-bdwgc) [mini-runtime.c:3445] mono_jit_runtime_invoke
0x00007ffab1d7e764 (mono-2.0-bdwgc) [object.c:3066] do_runtime_invoke
0x00007ffab1db9ed7 (mono-2.0-bdwgc) [threadpool.c:386] worker_callback
0x00007ffab1dbcf70 (mono-2.0-bdwgc) [threadpool-worker-default.c:502] worker_thread
0x00007ffab1dab96b (mono-2.0-bdwgc) [threads.c:1268] start_wrapper_internal
0x00007ffab1dabb46 (mono-2.0-bdwgc) [threads.c:1344] start_wrapper
0x00007ffaf0ea7034 (KERNEL32) BaseThreadInitThunk
0x00007ffaf2aa26a1 (ntdll) RtlUserThreadStart
  • Вопрос задан
  • 83 просмотра
Решения вопроса 1
@Ezekiel4
Охотник на пиратов и сборщик монолитов
Если коротко, то всё из-за того, что вебсокет работает в ином, нежели юнити, потоке. Поток юнити обслуживает покадровую систему и имеет закрытую структуру. Вместо прямого запуска кода сделайте очередь команд, в которую помещайте то, что вам нужно запустить. Выглядеть это будет как-то так:

// очередь команд
private readonly ConcurrentQueue<Action> _Actions = new ConcurrentQueue<Action>();

// получаете сообщение - ставите в очередь
private void OnMessage(object sender, MessageEventArgs e) {
	_Actions.Enqueue(() => ReadResponse(e.Data));
}

// каждое обновление экрана запускаем всю очередь
private void Update() {
	while (_Actions.Count > 0)
		if (_Actions.TryDequeue(out var action))
			action?.Invoke();
}

// вот тут вы уже можете влиять на тот же текст
private void ReadResponse(string data) {
	// ваш код
}
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы