How to get Socket Id in Socket.io on Android? - android

I want to get the id of my socket running in Android. Everything is create normally and is able to send data back and forth but I need to get the Androids socket id for usage throughout the entire application. I have tried to find a solution but either they were outdated or does not work. Below is my latest attempt at solving this issue. With this attempt it errors saying that there are no elements in args[0]. I have also tried mSocket.id(); but that returns nothing.
public class GameSocket {
private Socket mSocket = null;
private static GameSocket mInstance;
public synchronized static GameSocket getInstance() {
if (mInstance == null) {
mInstance = new GameSocket();
}
return mInstance;
}
public void initialize() {
mSocket = IO.socket(URI.create(SERVER_URI));
mSocket.off();
mSocket.on(Socket.EVENT_CONNECT, new Emitter.Listener() {
#Override
public void call(Object... args) {
Log.d(GameSocket.class.getSimpleName(), "Event connection...");
mSocketId = args[0].toString();
Log.d("CONNECT ID", mSocketId);
}
})
.on(Socket.EVENT_ERROR, new Emitter.Listener() {
#Override
public void call(Object... args) {
if (args != null) {
Log.e(GameSocket.class.getSimpleName(), "Socket Event Error: " + args[0].toString());
}
}
});
}
}

Related

WebRTC Android - createPeerConnection() always returns null

I'm new to Android and WebRTC, and I have been struggling to get a p2p video connection working between a website and my android device. I have already gotten this working between two websites, so I'm fairly sure my issue lies in the Android side.
When I try to create a new PeerConnection object using PeerConnectionFactory.createPeerConnection(), the result is always null. I am using release vesion M58 of WebRTC.
PeerConnection.IceServer iceServer = new PeerConnection.IceServer("http://stun.stun.l.google.com:19302/");
List<PeerConnection.IceServer> servers = new ArrayList<PeerConnection.IceServer>();
servers.add(iceServer);
// Media Constraints
final MediaConstraints mediaConstraints = new MediaConstraints();
mediaConstraints.mandatory.add(new MediaConstraints.KeyValuePair("OfferToReceiveAudio", "true"));
mediaConstraints.mandatory.add(new MediaConstraints.KeyValuePair("OfferToReceiveVideo", "true"));
mediaConstraints.optional.add(new MediaConstraints.KeyValuePair("DtlsSrtpKeyAgreement", "true"));
// Set up remote rendering stuff
rootEGLBase = EglBase.create();
svr = (SurfaceViewRenderer) findViewById(R.id.remote_video);
svr.init(rootEGLBase.getEglBaseContext(), null);
svr.setScalingType(RendererCommon.ScalingType.SCALE_ASPECT_FIT);
svr.setZOrderMediaOverlay(true);
svr.setEnableHardwareScaler(true);
remoteProxyRenderer.setTarget(svr);
remoteRender = remoteProxyRenderer;
// Create a peer connection factory
PeerConnectionFactory.initializeAndroidGlobals(this.ctx, true);
PeerConnectionFactory.Options options = new PeerConnectionFactory.Options();
options.networkIgnoreMask = 0;
PeerConnectionFactory peerConnectionFactory = new PeerConnectionFactory(options);
// wait until my websocket has connected
System.out.println("waiting for websocket to be inited...");
while (this.ws == null);
System.out.println("done wait");
final WebSocket in_scope_ws = this.ws;
// create peer connection observer
PeerConnection.Observer pcObserver = new PeerConnection.Observer() {/* not included - mostly just prints */};
// Create peerconnection
final PeerConnection peerConnection = peerConnectionFactory.createPeerConnection(servers, mediaConstraints, pcObserver);
Here is the PeerConnection.Observer anonymous implementation that I removed from the above code. I'm sure that I'm doing a lot of other stuff wrong in here, but I figured I'd wait to solve this until I got the offer/answer exchange working first.
PeerConnection.Observer pcObserver = new PeerConnection.Observer() {
final String TAG = "PEER_CONNECTION_FACTORY";
#Override
public void onSignalingChange(PeerConnection.SignalingState signalingState) {
Log.d(TAG, "onSignalingChange");
}
#Override
public void onIceConnectionChange(PeerConnection.IceConnectionState iceConnectionState) {
Log.d(TAG, "onIceConnectionChange");
}
#Override
public void onIceConnectionReceivingChange(boolean b) {
Log.d(TAG, "onIceConnectionReceivingChange");
}
#Override
public void onIceGatheringChange(PeerConnection.IceGatheringState iceGatheringState) {
Log.d(TAG, "onIceGatheringChange");
}
// not sure what to put here
#Override
public void onIceCandidate(IceCandidate iceCandidate) {
System.out.println("AN ICE CANDIDATE HAS BEEN DISCOVERED");
if (iceCandidate != null && in_scope_ws != null) {
try {
JSONObject payload = new JSONObject();
payload.put("sdpMLineIndex", iceCandidate.sdpMLineIndex);
payload.put("sdpMid", iceCandidate.sdpMid);
payload.put("candidate", iceCandidate.sdp);
JSONObject candidateObject = new JSONObject();
candidateObject.put("ice", iceCandidate.toString());
in_scope_ws.sendText(candidateObject.toString());
} catch (JSONException e) {
e.printStackTrace();
}
//send ice candidate to server - probably need to convert to string and put in JSON object
// in_scope_ws.send("")
}
}
#Override
public void onIceCandidatesRemoved(IceCandidate[] iceCandidates) {
Log.d(TAG, "onIceCandidatesRemoved");
}
// pretty sure this is the only garbage I need right now
#Override
public void onAddStream(MediaStream mediaStream) {
System.out.println("IN ADD STREAM");
if(mediaStream.videoTracks.size()==0) {
Log.d("onAddStream", "NO REMOTE STREAM");
System.out.println("NO REMOTE STREAM (PRINTLN)");
}
mediaStream.videoTracks.get(0).addRenderer(new VideoRenderer (remoteRender));
// VideoRendererGui.update(remoteRender, 0, 0, 100, 100, RendererCommon.ScalingType.SCALE_ASPECT_FILL, false);
}
#Override
public void onRemoveStream(MediaStream mediaStream) {
Log.d(TAG, "onRemoveStream");
}
#Override
public void onDataChannel(DataChannel dataChannel) {
Log.d(TAG, "onDataChannel");
}
#Override
public void onRenegotiationNeeded() {
Log.d(TAG, "onRenegotiationNeeded");
}
#Override
public void onAddTrack(RtpReceiver rtpReceiver, MediaStream[] mediaStreams) { Log.d(TAG, "onAddTrack"); }
};
You can enable verbose logging to trace the problem.
org.webrtc.Logging.enableLogToDebugOutput(Logging.Severity.LS_VERBOSE);
Also make sure you have granted required runtime permissions (CAMERA, RECORD_AUTDIO)
you need to createLocalMediaStream and set videoHeight videoWidth,createVideoSource,createAudioSource
before you createPeerConnection.
Another problem that createPeerConnection() returning null could be with wrong configuration of IceServer, make sure you set correct IceServer and correct credentials.
I had the same issue. The peerConnection object was always returned as null.
In my case, the username for one of the turn servers was not set. After setting that, peerConnection object was created successfully.
val servers = listOf(
...,
PeerConnection.IceServer.builder("server_url")
.setUsername("user_name")
.setPassword("password")
.createIceServer()
...
) as MutableList<PeerConnection.IceServer>

Chromecast MediaRouteProviderService

I have strange issue, I am creating mediaprovider for chromecast using following code that works fine for first instance, list of devices is shown and once slected I use router.selectRoute(routeinfo);
but once I exit app this code unable to find Chromecast device, how ever when I remove app from running apps stack this code works fine again and show devices.
If no device is selected and app is exited using back press then also this code works fine
So what I am doing wrong here? what I think is resources are not cleared when my app exit in simple back pressed.
public class ChromecastRouteProviderService extends MediaRouteProviderService {
final String LOGTAG = "Chromecast";
private static final String CONTROL_CATEGORY = CastMediaControlIntent.categoryForCast(CastMediaControlIntent.DEFAULT_MEDIA_RECEIVER_APPLICATION_ID);
private static final MediaRouteSelector SELECTOR = new MediaRouteSelector.Builder().addControlCategory(CONTROL_CATEGORY)
.addControlCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK).build();
private IntentFilter controlFilter;
public ChromecastRouteProviderService() {
controlFilter = new IntentFilter();
}
public void onCreate() {
super.onCreate();
controlFilter.addCategory(IAppConstants.CATEGORY);
controlFilter.addCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK);
}
#Override
public MediaRouteProvider onCreateMediaRouteProvider() {
return new ChromecastRouteProvider(this);
}
class ChromecastRouteProvider extends MediaRouteProvider {
MediaRouter.Callback callback;
Hashtable routes;
public ChromecastRouteProvider(Context context) {
super(context);
routes = new Hashtable();
callback = new CastCallBack();
}
#Nullable
#Override
public RouteController onCreateRouteController(String routeId) {
MediaRouter.RouteInfo routeInfo = (MediaRouter.RouteInfo) routes.get(routeId);
if (routeInfo == null) {
return super.onCreateRouteController(routeId);
} else {
return new ChromecastRouteController(getContext(), routeInfo);
}
}
#Override
public void onDiscoveryRequestChanged(#Nullable MediaRouteDiscoveryRequest request) {
super.onDiscoveryRequestChanged(request);
if (request == null || !request.isActiveScan() || !request.isValid()) {
stopScan();
return;
}
if (!request.getSelector().hasControlCategory(IAppConstants.CATEGORY)) {
Log.i(LOGTAG, "Not scanning for non remote playback");
stopScan();
return;
} else {
Log.i(LOGTAG, "Scanning...");
mediarouter.addCallback(ChromecastRouteProviderService.SELECTOR, callback, MediaRouter.CALLBACK_FLAG_REQUEST_DISCOVERY);
return;
}
}
void updateDescriptor() {
final MediaRouteProviderDescriptor.Builder descriptor = new MediaRouteProviderDescriptor.Builder();
for (Iterator iterator = routes.values().iterator(); iterator.hasNext(); ) {
MediaRouter.RouteInfo routeinfo = (MediaRouter.RouteInfo) iterator.next();
try {
Bundle bundle = new Bundle();
bundle.putBoolean("has_upsell", true);
descriptor.addRoute(new MediaRouteDescriptor.Builder(routeinfo.getId(), routeinfo.getName())
.addControlFilter(controlFilter).setPlaybackStream(3)
.setDescription(routeinfo.getDescription())
.setEnabled(true).setPlaybackType(MediaRouter.RouteInfo.PLAYBACK_TYPE_REMOTE)
.setVolumeHandling(1).setVolumeMax(100).setVolume(100)
.setExtras(bundle).build());
} catch (Exception e) {
throw new Error("wtf");
}
}
getHandler().post(new Runnable() {
#Override
public void run() {
setDescriptor(descriptor.build());
}
});
}
void stopScan() {
Log.i(LOGTAG, "Stopping scan...");
try {
MediaRouter.getInstance(getContext()).removeCallback(callback);
return;
} catch (Exception exception) {
return;
}
}
class CastCallBack extends MediaRouter.Callback {
void check(MediaRouter mediarouter, MediaRouter.RouteInfo routeinfo) {
Log.i(LOGTAG, new StringBuilder().append("Checking route ").append
(routeinfo.getName()).toString());
CastDevice device = CastDevice.getFromBundle(routeinfo.getExtras());
if (routeinfo.matchesSelector(ChromecastRouteProviderService.SELECTOR)
&& device != null && device.isOnLocalNetwork()) {
routes.put(routeinfo.getId(), routeinfo);
updateDescriptor();
return;
} else {
return;
}
}
public void onRouteAdded(MediaRouter mediarouter, MediaRouter.RouteInfo routeinfo) {
super.onRouteAdded(mediarouter, routeinfo);
check(mediarouter, routeinfo);
}
public void onRouteChanged(MediaRouter mediarouter, MediaRouter.RouteInfo routeinfo) {
super.onRouteChanged(mediarouter, routeinfo);
check(mediarouter, routeinfo);
}
public void onRouteRemoved(MediaRouter mediarouter, MediaRouter.RouteInfo routeinfo) {
super.onRouteRemoved(mediarouter, routeinfo);
if (routeinfo.matchesSelector(ChromecastRouteProviderService.SELECTOR)) ;
}
}
}
}
Ok finally I found answer on my own,
Problem is when any provider is selected it's not added using onRouteAdded why? I really dont understand google logic
So the solution is to unselect the router when you want or better select default route when so that your route is released
MediaRouter.getInstance(this).getDefaultRoute().select();
But again 1 out of 10 times it will not work
Hope will help someone

Server response Timeout function in parse.com android

I am working on parse.com android application. Like in normal http request if we don't get the response from the server in a certain time then it will show time out functionality. For example my following code will works for http request time out:
HttpsURLConnection connection = null;
connection = (HttpsURLConnection) serverAddress.openConnection();
connection.setRequestMethod("GET");
connection.setDoOutput(true);
connection.setHostnameVerifier(DO_NOT_VERIFY);
connection.setReadTimeout(3*1000);
Now i want the same functionality in parse.com, if i can't get the response from the parse server because of any reason like internet connectivity issue, then it will gives me timeout.
Thanks in advance.
Parse.com SDK does not have such functionality which you have described at your question.
But you can do some trick, for example, at ParseQuery exists method cancel(). So if you want timeout less then standard one, you can run query in background and and wait until or query callback will delivery result of it, or your implementation of timeout will cancel query running.
Update:
public class TimeoutQuery<T extends ParseObject> {
private ParseQuery<T> mQuery;
private final long mTimeout;
private FindCallback<T> mCallback;
private final Object mLock = new Object();
private final Thread mThread;
public TimeoutQuery(ParseQuery<T> query, long timeout) {
mQuery = query;
mTimeout = timeout;
mThread = new Thread() {
#Override
public void run() {
if (isInterrupted()) return;
try {
Thread.sleep(mTimeout);
} catch (InterruptedException e) {
return;
}
cancelQuery();
}
};
}
private void cancelQuery() {
synchronized (mLock) {
if (null == mQuery) return; // it's already canceled
mQuery.cancel();
new Handler(Looper.getMainLooper()).post(new Runnable() {
#Override
public void run() {
mCallback.done(Collections.<T>emptyList(), new ParseException(ParseException.TIMEOUT, ""));
}
});
}
}
public void findInBackground(final FindCallback<T> callback) {
synchronized (mLock) {
mCallback = callback;
mQuery.findInBackground(new FindCallback<T>() {
#Override
public void done(List<T> ts, ParseException e) {
synchronized (mLock) {
mThread.interrupt();
mQuery = null;
mCallback.done(ts, e);
}
}
});
mThread.start();
}
}
}
Usage:
ParseQuery<ParseObject> query = ParseQuery.getQuery("Test");
new TimeoutQuery<>(query, 1000).findInBackground(new FindCallback<ParseObject>() {
...
});

Android App Connecting to Node.js server using Socket.io

I'm having trouble getting my Android app to connect to a socket.io chat server. I'm using socket.io-java-client created by Gottox which can be found here: https://github.com/Gottox/socket.io-java-client
The server runs locally over port 7000. I'm using the android emulator, so I'm using 10.0.2.2:7000 to access the server.
Any help would be appreciated, I don't have much experience at all with SSL. If I find a working solution I'll also post it.
Node.js Server
var express = require('express');
var app = express();
var server = require('http').createServer(app).listen(7000);
var io = require('socket.io').listen(server);
io.sockets.on('connection', function(client){
client.on('message', function(err, msg){
client.broadcast.emit('message', msg);
});
});
package.json
{
"name": "simplechat",
"version": "0.0.1",
"main": "app.js",
"dependencies": {
"express" : "~4.0.0",
"socket.io" : "~0.9.13"
}
}
Android: SendMessageActivity
public class SendMessageActivity extends Activity {
private static final String SERVER_ADDRESS = "https://10.0.2.2:7000";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_send_message);
System.out.println("Sever: " + SERVER_ADDRESS);
try {
SocketIO socket = new SocketIO(new URL(SERVER_ADDRESS), new IOCallback() {
#Override
public void onDisconnect() {
System.out.println("disconnected");
}
#Override
public void onConnect() {
System.out.println("connected");
}
#Override
public void onMessage(String s, IOAcknowledge ioAcknowledge) {
}
#Override
public void onMessage(JSONObject jsonObject, IOAcknowledge ioAcknowledge) {
}
#Override
public void on(String event, IOAcknowledge ioAcknowledge, Object... objects) {
}
#Override
public void onError(SocketIOException e) {
e.printStackTrace();
}
});
} catch (MalformedURLException ex) {
ex.printStackTrace();
}
}
Android Permissions
<uses-permission
android:name="android.permission.INTERNET">
</uses-permission>
Error Code
08-09 16:07:28.224 8411-8441/com.example.puma.chatexample W/System.err﹕ io.socket.SocketIOException: Error while handshaking
08-09 16:07:28.225 8411-8441/com.example.puma.chatexample W/System.err﹕ at io.socket.IOConnection.handshake(IOConnection.java:322)
08-09 16:07:28.225 8411-8441/com.example.puma.chatexample W/System.err﹕ at io.socket.IOConnection.access$600(IOConnection.java:39)
08-09 16:07:28.225 8411-8441/com.example.puma.chatexample W/System.err﹕ at io.socket.IOConnection$ConnectThread.run(IOConnection.java:199)
08-09 16:07:28.226 8411-8441/com.example.puma.chatexample W/System.err﹕ Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'javax.net.ssl.SSLSocketFactory javax.net.ssl.SSLContext.getSocketFactory()' on a null object reference
08-09 16:07:28.226 8411-8441/com.example.puma.chatexample W/System.err﹕ at io.socket.IOConnection.handshake(IOConnection.java:302)
08-09 16:07:28.227 8411-8441/com.example.puma.chatexample W/System.err﹕ ... 2 more
I actually solved the problem. I used my PC's local IP http://192.168.0.xxx:7000 and the app was able to connect to the chat server from the emulator. I don't know why this works, but it might help out someone in the future :)
Update:
This is how I ended up structuring the project. I created a singleton class to handle socket connections Android side (you could also do it as a service). When receiving a message, the singleton class broadcasts an intent to the rest of the app. The intent is then picked up by a broadcast receiver in the relevant activity.
Android Side (singleton):
public class SocketSingleton {
private static SocketSingleton instance;
private static final String SERVER_ADDRESS = "http://1.2.3.4:1234";
private SocketIO socket;
private Context context;
public static SocketSingleton get(Context context){
if(instance == null){
instance = getSync(context);
}
instance.context = context;
return instance;
}
public static synchronized SocketSingleton getSync(Context context){
if (instance == null) {
instance = new SocketSingleton(context);
}
return instance;
}
public SocketIO getSocket(){
return this.socket;
}
private SocketSingleton(Context context){
this.context = context;
this.socket = getChatServerSocket();
this.friends = new ArrayList<Friend>();
}
private SocketIO getChatServerSocket(){
try {
SocketIO socket = new SocketIO(new URL(SERVER_ADDRESS), new IOCallback() {
#Override
public void onDisconnect() {
System.out.println("disconnected");
}
#Override
public void onConnect() {
System.out.println("connected");
}
#Override
public void on(String event, IOAcknowledge ioAcknowledge, Object... objects) {
if (event.equals("chatMessage")) {
JSONObject json = (JSONObject) objects[0];
ChatMessage chatMessage = new ChatMessage(json);
Intent intent = new Intent();
intent.setAction("newChatMessage");
intent.putExtra("chatMessage", chatMessage);
context.sendBroadcast(intent);
}
}
#Override
public void onError(SocketIOException e) {
e.printStackTrace();
}
});
return socket;
} catch (MalformedURLException ex) {
ex.printStackTrace();
}
return null;
}
}
Android Side (activity):
public class ChatActivity extends Activity {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chat);
IntentFilter newChatMessageFilter = new IntentFilter("newChatMessage");
this.registerReceiver(new MessageReceiver(), newChatMessageFilter);
...
public class MessageReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent){
final ChatMessage chatMessage =(ChatMessage) intent.getExtras().get("chatMessage");
runOnUiThread(new Runnable() {
#Override
public void run() {
mAdapter.add(chatMessage);
mAdapter.notifyDataSetChanged();
}
});
}
}
}
Server Side:
var express = require('express');
var app = express();
var server = require('http').createServer(app).listen(1234);
var io = require('socket.io').listen(server);
io.sockets.on('connection', function(client){
console.log("client connected: " + client.id);
client.on("sendTo", function(chatMessage){
console.log("Message From: " + chatMessage.fromName);
console.log("Message To: " + chatMessage.toName);
io.sockets.socket(chatMessage.toClientID).emit("chatMessage", {"fromName" : chatMessage.fromName,
"toName" : chatMessage.toName,
"toClientID" : chatMessage.toClientID,
"msg" : chatMessage.msg});
});
});
I know this not really answers to the OP's posts, but for those who may be interested, this is a tutorial I made to make communicate your Android with a Node.js server -without any additional library- :
https://causeyourestuck.io/2016/04/27/node-js-android-tcpip/
This is a foretaste of how it looks like at the end:
Client socket = new Client("192.168.0.8", 1234);
socket.setOnEventOccurred(new Client.OnEventOccurred() {
#Override
public void onMessage(String message) {
}
#Override
public void onConnected(Socket socket) {
socket.send("Hello World!");
socket.disconnect();
}
#Override
public void onDisconnected(Socket socket, String message) {
}
});
socket.connect();
Puma has already answered on how you can implement a socket connection using SocketIO. This has nothing new to contribute. Yet, it is an attempt to help fellow newbies, as also introduce the implementation of Socket.io's java library.
Socket.IO has its own java implementation on Github, which you can follow along to create a socket application for Android/Java.
Android side:
Include this in your build gradle
compile ('io.socket:socket.io-client:0.8.3') {
// excluding org.json which is provided by Android
exclude group: 'org.json', module: 'json'
}
Provide Permission in your app:
<uses-permission android:name="android.permission.INTERNET" />
Android Code:
The structure of code is similar to how you would code in Node. The message in socket.on is similar to node's socket.on('message', ...)
import io.socket.client.Socket;
import io.socket.client.IO;
import io.socket.emitter.Emitter;
final Socket socket;
try{
socket = IO.socket("http://192.168.1.1:8080");
socket.on(Socket.EVENT_CONNECT, new Emitter.Listener() {
#Override
public void call(Object... args) {
socket.emit("message", "hi");
socket.disconnect();
}
}).on("message", new Emitter.Listener() {
//message is the keyword for communication exchanges
#Override
public void call(Object... args) {
socket.emit("message", "hi");
}
}).on(Socket.EVENT_DISCONNECT, new Emitter.Listener() {
#Override
public void call(Object... args) {}
});
socket.connect();
}
catch(Exception e){
}
Node.js side
Create normal sockets using socket.io
You're emulator network is different from your PC's as I have heard. So if you could by change try this on an actual phone that is connected to the same network as your PC.
You probably wont be able to ping 10.0.2.2 from your emulator or the other way around from your pc to emulator.

Servlet WebSocket Acessed by Android

I'm trying learn how to use the websocket and make a simple servlet for being connected with Android but I don't get it.
The index.jsp :
var ws = new WebSocket("ws://" + document.location.host + "/myws/ServletWS");
ws.onopen = function() { };
ws.onclose = function() { };
ws.onerror = function() { log("ERROR"); };
ws.onmessage = function(data) { var message = data.data; };
function sendMessage(msg) { ws.send(msg); }
How or where I receive the data from client?
Now on the servlet:
#Override protected StreamInbound createWebSocketInbound(String subProtocol, HttpServletRequest request) {
return new ConnectionWS();
}
class ConnectionWS extends MessageInbound {
private WsOutbound outbound;
#Override protected void onOpen(WsOutbound outbound) {
this.outbound = outbound;
}
#Override protected void onTextMessage(CharBuffer msg) throws IOException {
String message = msg.toString();
ServletWS.processData(message);
}
public void sendMessage(String message) {
CharBuffer cb = CharBuffer.wrap(message);
try {
outbound.writeTextMessage(cb);
} catch (IOException e) {}
}
}
public void processData(String message){
here I have to call the sendMessage with the answer to the client
}
I have saw a lot of examples on web but all of then about chat.
Thanks a lot for any help.
I understand that, you have a basic knowledge about tomcat configuration as well as java Servlet programming. As WekSocket is newly introduced in Tomcat, you may need to use latest tomcat version to implement WebSocket over it. I have used Apache Tomcat 7.0.42 for it.
So here we go. First, create a Servlet which will just create a new WebSocket for the request. You may need to modify it, if you want to go by session rather than request. Here is sample code.
import org.apache.catalina.websocket.StreamInbound;
import org.apache.catalina.websocket.WebSocketServlet;
public class WsChatServlet extends WebSocketServlet {
private static final long serialVersionUID = 1456546233L;
#Override
protected StreamInbound createWebSocketInbound(String protocol,
HttpServletRequest request) {
return new IncomingMessageHandler();
}
}
Now, create a Message Handler class which will handle each WebSocket stream independently. and that's it !
public class IncomingMessageHandler extends MessageInbound {
private WsOutbound myoutbound;
public IncomingMessageHandler() {
}
#Override
public void onOpen(WsOutbound outbound) {
logger.info("Open Client.");
this.myoutbound = outbound;
}
#Override
public void onClose(int status) {
logger.info("Close Client.");
}
/**
* Called when received plain Text Message
*/
#Override
public void onTextMessage(CharBuffer cb) throws IOException {
}
/**
* We can use this method to pass image binary data, eventually !
*/
#Override
public void onBinaryMessage(ByteBuffer bb) throws IOException {
}
public synchronized void sendTextMessage(String message) {
try {
CharBuffer buffer = CharBuffer.wrap(message);
this.getMyoutbound().writeTextMessage(buffer);
this.getMyoutbound().flush();
} catch (IOException e) {
}
}
/**
* Set websocket connection timeout in milliseconds,
* -1 means never
*/
#Override
public int getReadTimeout() {
return -1;
}
public WsOutbound getMyoutbound() {
return myoutbound;
}
public void setMyoutbound(WsOutbound myoutbound) {
this.myoutbound = myoutbound;
}
}
If not misunderstood and you want to use web sockets on Android then recommended API for you is jWebSocket.
Get it here, hopefully it already provides you APIs for a lot of the work that you need to do or even more.
http://jwebsocket.org/

Categories

Resources