We've recently reorganized our socket connections to have them use more shared code. I currently have the iOS project able to connect to the web socket and respond to events but I haven't been successful yet with the android project. It will try to connect and eventually hit the disconnect event with data stating "transport error". I'm wondering if anyone with more experience with sockets knows if there are any key differences between an iOS connection and an android connection? I'll post some of my code below and try to cut out the chunks I don't think are related. Thank you!!
This is my shared class
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));
}
}
this is my android class
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();
}
My iOS class looks really similar to the droid class.. besides the Open().. Not sure what is hanging up on the android side.