Issue
I'm currently building a multiplayer game in Kotlin/Java and I wanted to use the nakama framework for the backend. I was working on the match-joining system when I noticed that I don't get callbacks from the SocketListener interface of the nakama library. I don't know why this happens
The interface of nakama (java):
public interface SocketListener {
/**
* Called when the client socket disconnects.
*
* Throwable t is set if an error caused the disconnect.
*/
void onDisconnect(final Throwable t);
/**
* Called when the client receives an error.
*
* @param error The {@code Error} received.
*/
void onError(final Error error);
/**
* Called when a new topic message has been received.
*
* @param message The {@code ChannelMessage} received.
*/
void onChannelMessage(final ChannelMessage message);
/**
* Called when a new topic presence update has been received.
*
* @param presence The {@code ChannelPresenceEvent} received.
*/
void onChannelPresence(final ChannelPresenceEvent presence);
/**
* Called when a matchmaking has found a match.
*
* @param matched The {@code MatchmakerMatched} received.
*/
void onMatchmakerMatched(final MatchmakerMatched matched);
/**
* Called when a new match data is received.
*
* @param matchData The {@code MatchData} received.
*/
void onMatchData(final MatchData matchData);
/**
* Called when a new match presence update is received.
*
* @param matchPresence The {@code MatchPresenceEvent} received.
*/
void onMatchPresence(final MatchPresenceEvent matchPresence);
/**
* Called when the client receives new notifications.
*
* @param notifications The list of {@code Notification} received.
*/
void onNotifications(final NotificationList notifications);
/**
* Called when the client receives status presence updates.
*
* @param presence Updated {@code StatusPresenceEvent} presence.
*/
void onStatusPresence(final StatusPresenceEvent presence);
/**
* Called when the client receives stream presence updates.
*
* @param presence Updated {@code StreamPresenceEvent} presence.
*/
void onStreamPresence(final StreamPresenceEvent presence);
/**
* Called when the client receives stream data.
*
* @param data Stream {@code StreamData} data received.
*/
void onStreamData(final StreamData data);
}
My implementation in Kotlin:
class MSocketListener : SocketListener {
override fun onDisconnect(t: Throwable?) {
TODO("Not yet implemented")
}
override fun onError(error: Error?) {
TODO("Not yet implemented")
}
override fun onChannelMessage(message: ChannelMessage?) {
TODO("Not yet implemented")
}
override fun onChannelPresence(presence: ChannelPresenceEvent?) {
TODO("Not yet implemented")
}
override fun onMatchmakerMatched(matched: MatchmakerMatched?) {
TODO("Not yet implemented")
}
override fun onMatchData(matchData: MatchData?) {
TODO("Not yet implemented")
}
override fun onMatchPresence(matchPresence: MatchPresenceEvent?) {
TODO("Not yet implemented")
}
override fun onNotifications(notifications: NotificationList?) {
TODO("Not yet implemented")
}
override fun onStatusPresence(presence: StatusPresenceEvent?) {
TODO("Not yet implemented")
}
override fun onStreamPresence(presence: StreamPresenceEvent?) {
TODO("Not yet implemented")
}
override fun onStreamData(data: StreamData?) {
TODO("Not yet implemented")
}
}
Does anybody know why I don't get callbacks? Thanks in advance
Edit: I've now also tried implementing the interface in a java class.. still no callback
Java Class (basically the same code as the Kotlin class, just in java):
public class NakamaTest implements SocketListener {
@Override
public void onDisconnect(Throwable t) {
//code
}
@Override
public void onError(Error error) {
//code
}
@Override
public void onChannelMessage(ChannelMessage message) {
//code
}
@Override
public void onChannelPresence(ChannelPresenceEvent presence) {
//code
}
@Override
public void onMatchmakerMatched(MatchmakerMatched matched) {
//code
}
@Override
public void onMatchData(MatchData matchData) {
//code
}
@Override
public void onMatchPresence(MatchPresenceEvent matchPresence) {
//code
}
@Override
public void onNotifications(NotificationList notifications) {
//code
}
@Override
public void onStatusPresence(StatusPresenceEvent presence) {
//code
}
@Override
public void onStreamPresence(StreamPresenceEvent presence) {
//code
}
@Override
public void onStreamData(StreamData data) {
//code
}
}
Solution
After a lot of trial and error I finally solved it. I'm posting this here for the rare case anybody will have the same problem.
First of all, I had to use the AbstractSocketListener
not the SocketListener
, which are both provided from the Nakama Framework.
Then you have to create a listener variable like this:
val listener: SocketListener = object : AbstractSocketListener() {
override fun onMatchPresence(matchPresence: MatchPresenceEvent?) {
super.onMatchPresence(matchPresence)
//code
}
}
I chose the onMatchPresence
callback as an example, but you can use all callbacks Nakama provides, which are for example listed in the code block of my question above, or in the documentation for Java. If you are using android studio, you can just start by typing override fun *name of callback*
and then press Tab
. Android Studio should automatically create the rest of the function for you.
In the next step, we need our socket. If you haven't created one yet:
val client: Client = DefaultClient("defaultkey")
val socket: SocketClient = client.createSocket()
For more information about the creation of the client and the socket check out the getting started section of the docs
After that, our last step is to link our listener to our socket, which can be done as follows:
socket.connect(session, listener).get()
After that, you should be set to go! You can place the code you want to execute when you get the callback in the section I marked with the comment.
Answered By - Liam K.
Answer Checked By - Clifford M. (JavaFixing Volunteer)