与 Xamarin.Forms Android 项目建立 WebSocket4Net 连接时遇到问题
Posted
技术标签:
【中文标题】与 Xamarin.Forms Android 项目建立 WebSocket4Net 连接时遇到问题【英文标题】:Trouble establishing WebSocket4Net connection with Xamarin.Forms Android project 【发布时间】:2019-09-26 15:26:51 【问题描述】:我们最近重新组织了套接字连接,让它们使用更多共享代码。我目前的 ios 项目能够连接到 Web 套接字并响应事件,但我还没有成功使用 android 项目。它将尝试连接并最终使用“传输错误”的数据触发断开连接事件。我想知道是否有更多使用套接字经验的人知道 iOS 连接和 android 连接之间是否存在任何关键区别?我将在下面发布我的一些代码,并尝试删除我认为不相关的块。谢谢!!
这是我的共享课
public bool InitAndConnect()
//Create a socket
sock = DependencyService.Get<IDabSocket>(DependencyFetchTarget.NewInstance);
//Get the URL to use
ContentConfig config = ContentConfig.Instance;
string uri;
if (GlobalResources.TestMode)
uri = config.app_settings.stage_journal_link;
else
uri = config.app_settings.prod_journal_link;
//Create list of events to monitor (basic connection events are already monitored)
List<String> events = new List<String>();
events.Add("room_error");
events.Add("join_error");
events.Add("auth_error");
events.Add("update");
//Register for notifications from the socket
sock.DabSocketEvent += Sock_DabSocketEvent;
//Init the socket
sock.Init(uri, events);
//Connect the socket
sock.Connect();
return true;
public bool JoinRoom(DateTime date)
//Joins a room for a specific date
var room = date.ToString("yyyy-MM-dd");
var token = AuthenticationAPI.CurrentToken;
var data = new DabJournalObject(room, token);
var json = JObject.FromObject(data);
//Send data to the socket
sock.Emit("join", json);
//Store the date we're using
currentDate = date;
return true;
//IsConnected returns a bool indicating whether the socket is currently connected.
//This is a bindable property
public bool IsConnected
get
return sock == null ? false : sock.IsConnected;
//Opposite of IsConnected used for binding reasons.
public bool IsDisconnected
get
return sock == null ? true : !sock.IsConnected;
private void Sock_DabSocketEvent(object sender, DabSocketEventHandler e)
//An event has been fired by the socket. Respond accordingly
//Log the event to the debugger
Debug.WriteLine($"e.eventName was fired with e.data");
//Take action on the event
switch (e.eventName.ToLower())
case "disconnected": //Socket disconnected
Sock_Disconnected(e.data);
break;
case "connected": //Socket connected
Sock_Connected(e.data);
break;
case "reconnecting": //Socket reconnecting
sock.Connect();
//do nothing for now
break;
case "reconnected": //Socket reconnected
Sock_Connected(e.data);
break;
case "room_error": //Error with a room
Sock_ErrorOccured(e.eventName, e.data);
break;
case "join_error": //Error joining
Sock_ErrorOccured(e.eventName, e.data);
break;
case "auth_error": //Error with authentication
Sock_ErrorOccured(e.eventName, e.data);
break;
case "update": //update happened externally
Sock_ExternalUpdateOccured(e.eventName, e.data);
break;
default:
break;
private void Sock_Disconnected(string data)
//The socket got disconnected.
//Notify UI
OnPropertyChanged("IsConnected");
OnPropertyChanged("IsDisconnected");
private void Sock_Connected(object data)
//The socket has connected or reconnected. Take appropriate action
//Notify UI
OnPropertyChanged("IsConnected");
OnPropertyChanged("IsDisconnected");
/* Events to handle Binding */
public virtual void OnPropertyChanged(string propertyName = null)
var handler = PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs(propertyName));
这是我的安卓类
public bool IsConnected
get
return isConnected;
public void Connect(string token)
//Make sure the socket is initialized
if (!isInitialized) throw new Exception("You must initialize the socket before using it");
sock.Connect();
public void Init(string Uri, List<String> events)
//Initialize the socket
try
sock = IO.Socket(Uri);
isInitialized = true;
//Set up standard events
sock.On("connect", data => OnConnect(data));
sock.On("disconnect", data => OnDisconnect(data));
sock.On("reconnect", data => OnReconnect(data));
sock.On("reconnecting", data => OnReconnecting(data));
//Set up custom events requested by the caller
foreach (string s in events)
sock.On(s, data => OnEvent(s, data));
catch (Exception ex)
isInitialized = false;
isConnected = false;
private object OnEvent(string s, object data)
//A requested event has fired - notify the calling app so it can handle it.
//Notify the listener
DabSocketEvent?.Invoke(this, new DabSocketEventHandler(s, data.ToString()));
return data;
private object OnConnect(object data)
//Socket has connected (1st time)
isConnected = true;
//Notify the listener
DabSocketEvent?.Invoke(this, new DabSocketEventHandler("connected", data.ToString()));
//Return
return data;
private object OnDisconnect(object data)
//Socket has disconnected
isConnected = false;
//Notify the listener
DabSocketEvent?.Invoke(this, new DabSocketEventHandler("disconnected", data.ToString()));
//Return
return data;
public void Disconnect()
if (IsConnected)
sock.Disconnect();
public void Connect()
sock.Connect();
public void Emit(string Command, object Data)
sock.Emit(Command, Data);
public void Open()
sock.Open();
我的 iOS 类看起来非常类似于 droid 类.. 除了 Open().. 不知道 android 端挂了什么。
【问题讨论】:
在android中建立WebSocket4Net连接时,能否请您发布一些错误信息? 我现在正在运行代码,但我并没有真正得到任何错误,它只是没有在 android 端建立连接。不断返回false。我初始化并尝试连接套接字,然后尝试加入房间,但到目前为止我无法建立与套接字的连接。 在我的三元运算符中,出于某种原因,我的 iOS 类正在适当地返回 sock.IsConnected,但在上面的 droid 类中,它总是返回 sock.IsConnected == false。 @JessieZhang 您可以尝试逐步调试请求,然后您可以看到有关此问题的详细信息。 【参考方案1】:我的 SocketIoClientDotNet nuget 包版本在我的 iOS 和 android 项目之间不匹配。一旦我更新了我的 android 包以匹配 iOS 项目中的版本,一切都很好。
【讨论】:
以上是关于与 Xamarin.Forms Android 项目建立 WebSocket4Net 连接时遇到问题的主要内容,如果未能解决你的问题,请参考以下文章
关于xamarin.forms Android创建文件与写文件 (ftp)
张高兴的 Xamarin.Forms 开发笔记:为 Android 与 iOS 引入 UWP 风格的汉堡菜单 ( MasterDetailPage )
Xamarin Forms Android .APK 与 .AAB(捆绑包)