Create a thread to send and wait for response (websockets) - java

Have a method to connect to socket and send the message and sleep for a sec to process the response.
import com.ning.http.client.AsyncHttpClient;
import com.ning.http.client.websocket.WebSocket;
import com.ning.http.client.websocket.WebSocketTextListener;
import com.ning.http.client.websocket.WebSocketUpgradeHandler;
import org.codehaus.jettison.json.JSONArray;
import org.codehaus.jettison.json.JSONObject;
import org.jboss.netty.handler.codec.http.HttpHeaders;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
public class SocketClient implements WebSocketTextListener {
private static org.slf4j.Logger log = LoggerFactory.getLogger(SocketClient.class);
private WebSocket websocket;
private List<String> serverResponse = new ArrayList<String>();
private List<String> logFromResponse = new ArrayList<String>();
public List<String> getAllLogs(String receiverId){
logFromResponse = new ArrayList<String>();
JSONObject jObj = new JSONObject();
try {
jObj.put("deviceId", receiverId);
}catch(Exception e){
log.warn("JSON Exception: "+e.getLocalizedMessage(), e);
}
connectToSocket();
if (websocket!=null)
websocket.sendTextMessage(jObj.toString());
responseFromServer();
return logFromResponse;
}
public boolean clearForDevice(String receiverId){
JSONObject jObj = new JSONObject();
try {
jObj.put("deviceId", receiverId);
}catch(Exception e){
log.warn("JSON Exception: "+e.getLocalizedMessage(), e);
}
connectToSocket();
if (websocket!=null)
websocket.sendTextMessage(jObj.toString());
String res = responseFromServer();
return (res!=null) && res.contains("Success");
}
private void connectToSocket() {
AsyncHttpClient c = new AsyncHttpClient();
AsyncHttpClient.BoundRequestBuilder builder = c.prepareGet(createUri())
.addHeader(HttpHeaders.Names.CONNECTION, "Upgrade")
.addHeader(HttpHeaders.Names.UPGRADE, "WebSocket");
websocket = builder.execute(new WebSocketUpgradeHandler.Builder()
.addWebSocketListener(this).build()).get();
}
#Override
public void onOpen(WebSocket webSocket) {
log.debug("Opening WebSocket");
}
#Override
public void onClose(WebSocket webSocket) {
log.debug("Closing WebSocket");
}
#Override
public void onError(Throwable throwable) { }
#Override
public void onMessage(String message) {
serverResponse.add(message);
}
#Override
public void onFragment(String s, boolean b) { }
private String responseFromServer() {
String response = null;
sleep(100);
if (!serverResponse.isEmpty()) {
//format message and send response and add to logFromResponse
}
return response;
}
protected void sleep(long millis) {
try {
Thread.sleep(millis);
} catch (InterruptedException e) {
log.warn("Interrupted Exception: "+e.getLocalizedMessage(), e);
}
}
}
but, I want to do it without the sleep() for 1 sec, Connecting to socket using AsyncHttpClient which is not Blocking io. I would like to create a thread which can send the message and wait for the response from the server? I did try to create a class by implementing runnable interface but no luck!
Any suggestions how to create synchronous call to websockets or Blocking IO.
UPDATE: Using synchronized blocks to wait and then notify once the message is received! Followed #Antoniossss comment

Straight from Ning home page
import com.ning.http.client.*;
import java.util.concurrent.Future;
AsyncHttpClient asyncHttpClient = new AsyncHttpClient();
Future<Response> f = asyncHttpClient.prepareGet("http://www.ning.com/").execute(); //here you will execute async request
Response r = f.get(); // here you will block until respons is accessible;
So I guess that AsyncHttpClient is designed to be Sync if needed as this piece of code will block and wait for the response. When you invoke get() after some time, probably response will be accessible right away as the request has been finished in meantime.
Now run both parts, execution and response reding in new thread, or execute request in main thread, and wait for the response (the get() part) in background thread - voila

Related

Is there any way to delay Async NIO server response in Java?

Having trouble 'delaying' the response of server, which is passed to client side.
What I'm trying to do is, just make an echoing, asynchronous, Non-blocking server with NIO package.
Then, I want to manually delay the response sent to Client, to confirm that this server handles multiple response, while not blocked by any of its clients, delays observable by naked eyes.
The main server code is :
package AsyncServer;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.*;
import AsyncServer.AsyncHandler.*;
public class AsyncServer {
int port = 40000;
public AsyncServer () {}
public AsyncServer(int port) {this.port = port;}
protected void start()
{
System.out.println("Async Server running at port "+this.port);
try {
AsynchronousServerSocketChannel server = AsynchronousServerSocketChannel.open();
server.bind(new InetSocketAddress(this.port));
AcceptCompletionHandler ach = new AcceptCompletionHandler(server);
server.accept(null, ach);
System.in.read();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
package AsyncServer.AsyncHandler;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousServerSocketChannel;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
public class AcceptCompletionHandler implements CompletionHandler<AsynchronousSocketChannel, Void> {
private final AsynchronousServerSocketChannel ssc;
public AcceptCompletionHandler(AsynchronousServerSocketChannel in_ssc) {
this.ssc = in_ssc;
}
#Override
public void completed (AsynchronousSocketChannel sc, Void attachment) {
/*
This context was used in attempt to delay response sent to async client.
Does not work properly, only delaying server console output
try {
int amount = (int) (Math.random() * 20);
Thread.sleep(amount*1000);
System.out.println("slept for "+amount);
}
catch (InterruptedException e) {
e.printStackTrace();
}
*/
ssc.accept(null, this);
System.out.println("Connection Established");
ByteBuffer buffer = ByteBuffer.allocate(512);
ReadCompletionHandler rch = new ReadCompletionHandler(sc, buffer);
sc.read(buffer, null, rch);
//System.out.println("Received "+buffer.toString());
}
#Override
public void failed (Throwable T, Void attachment){
T.printStackTrace();
}
}
package AsyncServer.AsyncHandler;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
import java.nio.charset.*;
public class ReadCompletionHandler implements CompletionHandler<Integer, Void> {
private final AsynchronousSocketChannel sc;
private final ByteBuffer buffer;
ReadCompletionHandler (AsynchronousSocketChannel in_sc, ByteBuffer in_buffer) {
this.sc = in_sc;
this.buffer = in_buffer;
}
#Override
public void completed (Integer bytes, Void attachment) {
WriteCompletionHandler wch = new WriteCompletionHandler(this.sc);
this.buffer.flip();
this.sc.write(this.buffer, null, wch);
Charset charset = Charset.forName("UTF-8");
String outputStr = new String(this.buffer.array()).trim();
System.out.println("Writing "+outputStr+" into return buffer");
}
#Override
public void failed (Throwable T, Void attachment) {
T.printStackTrace();
}
}
package AsyncServer.AsyncHandler;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
public class WriteCompletionHandler implements CompletionHandler<Integer, Void> {
private final AsynchronousSocketChannel sc;
WriteCompletionHandler (AsynchronousSocketChannel in_sc) {
this.sc = in_sc;
}
#Override
public void completed (Integer bytes, Void attachment) {
try {
sc.close();
System.out.println("Socket closed");
}
catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void failed (Throwable T, Void attachment) {
T.printStackTrace();
}
}
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousSocketChannel;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
public class AsyncClient {
private String ip = "localhost";
private int port = 40000;
private String payload = "00209999997778222223";
AsyncClient(String in_ip, int in_port, String in_payload)
{
this.ip = in_ip;
this.port = in_port;
this.payload = in_payload;
}
AsyncClient() {}
void start()
{
try {
AsynchronousSocketChannel sc = AsynchronousSocketChannel.open();
SocketAddress serverAddr = new InetSocketAddress(this.ip, this.port);
Future<Void> res = sc.connect(serverAddr);
System.out.println("Will connect to remote");
res.get();
System.out.println("Connection Established");
String outStr = this.payload;
ByteBuffer buffer = ByteBuffer.wrap(outStr.getBytes());
Future<Integer> sender = sc.write(buffer);
sender.get();
buffer.flip();
Future<Integer> receiver = sc.read(buffer);
System.out.println("Received : "+new String(buffer.array()).trim());
receiver.get();
buffer.clear();
}
catch (IOException e) {
e.printStackTrace();
}
catch (InterruptedException e) {
e.printStackTrace();
}
catch (ExecutionException e) {
e.printStackTrace();
}
}
}
Client Code components are also available in here.
So this code calls on Custom completionHandler three times.
Control flow goes to AcceptCompletionHandler -> ReadCompletionHandler -> WriteCompletionHandler, when each accept, read, write is called.
As I mentioned earlier, what I wanted to achieve was delaying whole asynchronous receive-response stream of each client thread. By running Client code on multiple threads, Say, some delays 11s, other delay less than 10s, my bare eye could catch this asynchronous operation.
However, If I run multiple threads of AsyncClient, It appears that no delay happens. Almost Instantly, the response arrives at client side. However, delays are really delaying console output of server side. Like this one. Sorry for missing timestamps!
I added semaphore acquire&release to server object itself, wrap delay syntax with semaphore acquire&release. It seems that asyncSocketStream passes their work to any other Idle thread if it meets delay. So I wrapped whole server in ExecutorService package, limiting maximum thread to one. Still, the client gets its reponse right away, and meaningless waiting of server console output happens...
Please enlighten me if I'm doing what is very bad, since I'm new to Async socket programming.

What is the best method to use ObservableLists for both GUI and background Tasks?

SSCCE:
package sample;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.ListView;
import javafx.stage.Stage;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Semaphore;
public class Main extends Application {
#Override
public void start(Stage primaryStage) throws Exception{
ListView<Integer> root = new ListView<Integer>();
ObservableList<Integer> data = Model.getInstance().getData();
root.setItems(data);
// A Thread that simulates changes to GUI Observant List.
Thread populate = new Thread(()->{
for(int i=0;i<20000;i+=1){
int finalInstance = i;
// Changes are done on FXThread
Platform.runLater(()->{
data.add(finalInstance);
});
try{
Thread.sleep(5);
}catch(InterruptedException e){
e.printStackTrace();
}
}
});populate.start();
// Populates at 200 elements/s
// Server Thread that Sends current status of ObservableList<Integer> data
Thread server = new Thread(()->{
try{
// Server Socket
ServerSocket ss = new ServerSocket(5555);System.out.println("SERVER ONLINE:");
while(true){
Socket s = ss.accept();
// Client Handler Thread to Handle Clients
Thread clientHandler = new Thread(()->{
try{
System.out.println("SERVER CLIENT:"+s);
ObjectOutputStream oos = new ObjectOutputStream(s.getOutputStream());
List<Integer> dataCopy = new ArrayList<Integer>();
// Get Current Status of data List that is being used in FXThread adn store in dataCopy
Semaphore waitForReadToComplete = new Semaphore(0);
Platform.runLater(()->{
System.out.println("EXPECTED LENGTH: "+data.size());
for(Integer a:data){
dataCopy.add(a);
try{
Thread.sleep(5); // Simulate delay while copying large elements
}catch (InterruptedException e){e.printStackTrace();}
}
waitForReadToComplete.release(); // Marks Read Operation Complete
});
waitForReadToComplete.acquire();// Resumes Client Thread
oos.writeObject(dataCopy);oos.flush();
s.close();
}catch (InterruptedException | IOException e){
e.printStackTrace();
}
});clientHandler.start();
}
}catch(IOException e){
e.printStackTrace();
}
});server.start();
// Client Thread that requests for current status of ObservableList<Integer> data.
Thread client = new Thread(()->{
try{
Thread.sleep(1000);
Socket s = new Socket(InetAddress.getLocalHost(),5555);
ObjectInputStream ois = new ObjectInputStream(s.getInputStream());
List<Integer> dataCopy;
dataCopy = (ArrayList<Integer>)ois.readObject();
s.close();
System.out.println("ACTUAL LENGTH RECIEVED BY CLIENT "+dataCopy.size());
}catch (IOException | ClassNotFoundException | InterruptedException e){
e.printStackTrace();
}
});client.start();
primaryStage.setTitle("Hello World");
primaryStage.setScene(new Scene(root, 300, 275));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
// Singleton Class with Eager Initialization
class Model{
static Model onlyInstance = new Model();
ObservableList<Integer> data = FXCollections.<Integer>observableArrayList();
public static Model getInstance(){
return onlyInstance;
}
public ObservableList<Integer> getData(){
return data;
}
}
In this example, I intend to send over the status of the data List to a client when it connects to my Server Thread.
The problem is that every time I want to read the data List, I need to do it using a Platform.runLater() call, whose scheduling is not in my control.
I use a Semaphore to block the Server's Client Handler thread in order to make sure that the complete List is copied and then sent to the client.
As visible, This method makes my client wait for a longer period of time since copying the data List is done inside Platform.runLater().
I was wondering if there was a better way to share my data List between the FXThread and Background Threads.
EDIT:
Better wording, courtesy of #James_D
I have a model with some (possibly large amount of) data. The model is being updated by a background thread. The server has access to the model and sends the data on demand to network-connected clients. And then there's a UI, which is server-side. And I want the UI to display the current state of the model on the server-side and perform add/remove operations on the data from the UI user.
I suggest using a Model shared between the javafx Application, the modifying thread, and the server:
import javafx.application.Application;
import javafx.application.Platform;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.ListView;
import javafx.stage.Stage;
public class Main extends Application {
private Model model;
#Override
public void start(Stage primaryStage) throws Exception{
ListView<Integer> listView = new ListView<>();
ObservableList<Integer> data = listView.getItems();
model = new Model();
model.getData().addListener(
(ListChangeListener<Integer>) listener -> {
listener.next();
Platform.runLater(()-> data.addAll(listener.getAddedSubList()));
}
);
populate();
new Server(model, 5555).activate();
new Client("localhost",5555).activate();
primaryStage.setScene(new Scene(listView, 300, 275));
primaryStage.show();
}
private void populate() {
Thread populate = new Thread(()->{
for(int i=0;i<20000;i+=1){
model.addData(i);
try{
Thread.sleep(50);
}catch(InterruptedException e){
e.printStackTrace();
}
}
});populate.start();
}
public static void main(String[] args) {
launch(args);
}
}
class Model{
private final ObservableList<Integer> data = FXCollections.<Integer>observableArrayList();
private final ObservableList<Integer> readOnlyData = FXCollections.unmodifiableObservableList(data);
synchronized void addData(int i){
data.add(i);
}
public ObservableList<Integer> getData(){
return readOnlyData;
}
}
The Server definition, including ServerThread to support multiple clients:
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import javafx.collections.ObservableList;
public class Server {
private final ExecutorService pool;
private final List<ServerThread> clients;
private final int portNumber;
private boolean stop;
private ServerSocket serverSocket;
private final Model model;
Server(Model model, int portNumber) {
this.model = model;
this.portNumber = portNumber;
pool = Executors.newFixedThreadPool(3);
clients = new ArrayList<>();
}
private void runServer(){
System.out.println("SERVER: Waiting for client");
try{
serverSocket = new ServerSocket(portNumber);
stop = false;
while(! stop){//do in loop to support multiple clients
Socket clientSocket = serverSocket.accept();
System.out.println("SERVER: client connected");
ServerThread st1 = new ServerThread(model.getData(), clientSocket);
pool.execute(st1);
clients.add(st1);
}
} catch (IOException e) {
e.printStackTrace();
}finally {
closeSocket();
}
}
public void stop(){
for( ServerThread st : clients) {
st.stopServerTread();
}
stop = true;
pool.shutdown();
closeSocket();
}
public void activate(){
new Thread(()->runServer()).start();
}
private void closeSocket() {
try {
serverSocket.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
class ServerThread extends Thread {
private Socket socket = null;
private boolean stop;
private final ObservableList observableList;
public ServerThread(ObservableList<Integer> observableList ,Socket socket) {
this.observableList = observableList;
this.socket = socket;
}
#Override
public void run() {
try{
stop = false;
DataInputStream in = new DataInputStream( socket.getInputStream() );
DataOutputStream out = new DataOutputStream( socket.getOutputStream() );
String fromClient;
while(! stop){
if((fromClient = in.readUTF()) != null) {
System.out.println("SERVER: recieved message - " + fromClient);
out.writeUTF("Data size is " + observableList.size());
}
}
} catch (IOException e) {
e.printStackTrace();;
}
}
void stopServerTread(){
stop = true;
}
}
And finally the client which requests info from the server:
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.concurrent.TimeUnit;
public class Client{
private final int portNumber;
private final String hostName;
private boolean stop;
Client(String hostName, int portNumber ) {
this.hostName = hostName;
this.portNumber = portNumber;
}
private void runClient(){
try {
stop = false;
Socket socket = new Socket(hostName, portNumber);
DataInputStream in = new DataInputStream( socket.getInputStream() );
DataOutputStream out = new DataOutputStream( socket.getOutputStream() );
while (! stop) {
out.writeUTF("Request Size"); //any not null string to get server response
String fromServer = in.readUTF();
System.out.println(fromServer);
TimeUnit.SECONDS.sleep(1);
}
} catch (UnknownHostException e) {
e.printStackTrace();
System.exit(1);
} catch (IOException e) {
e.printStackTrace();
System.exit(1);
}catch (InterruptedException e){
e.printStackTrace();
}
}
public void activate(){
new Thread(()->runClient()).start();
}
public void stop(){
stop = true;
}
}
One thing that you could change is the order that your submitting your tasks. Instead of starting the client thread, then calling run later and waiting for the response. Just call Platform.runLater, populate the copy and then start the client thread. Now there is no reason for a semaphore.
// Immediately following the accept.
Platform.runLater(()->{
System.out.println("EXPECTED LENGTH: "+data.size());
List<Integer> dataCopy = new ArrayList<>(data);
Thread clientHandler = new Thread(()->{
try(ObjectOutputStream oos = new ObjectOutputStream(s.getOutputStream()) ) {
System.out.println("SERVER CLIENT:"+s);
oos.writeObject(dataCopy);
oos.flush();
}catch (InterruptedException | IOException e){
e.printStackTrace();
}
});
clientHandler.start();
});
Creating a new thread each time should be replaced with an executor service of some sort. Depending on the task, consider using javafx.concurrent Task. Your server loop could be a task for example.
It's possible to expose an view of the data backing your observable list.
List<String> cowal = new CopyOnWriteArrayList<>();
ObservableList<String> data = FXCollections.observableList(cowal);
List<String> dataCopy = Collections.unmodifiableList(cowal);
I made it a copy on write array list so you can iterate over the view without getting a CCME. I called it a dataCopy to be consistent with the previous naming, but it is a view of the data.
Also, as a matter of taste, instead of });server.start(); create a new line to call server.start();

What is the multi threading model in Java NIO 2 - (Proactor pattern)?

I am trying to build a simple Echo Service using Java NIO 2 (which is based on Proactor Pattern).
In the simplest implementation, we have 4 main components; ProactorInitiator, AcceptConnectionHandler, ReadConnectionHandler and WriteConnectionHandler.
Following is my sample code.
ProactorInitiator.java
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.AsynchronousServerSocketChannel;
public class ProactorInitiator {
static int ASYNC_SERVER_PORT = 4333;
public void initiateProactiveServer(int port)
throws IOException {
final AsynchronousServerSocketChannel listener =
AsynchronousServerSocketChannel.open().bind(
new InetSocketAddress(port));
AcceptCompletionHandler acceptCompletionHandler =
new AcceptCompletionHandler(listener);
SessionState state = new SessionState();
listener.accept(state, acceptCompletionHandler);
System.out.println("Proactor Initiator Running on "+Thread.currentThread().getName());
}
public static void main(String[] args) {
try {
System.out.println("Async server listening on port : " +
ASYNC_SERVER_PORT);
new ProactorInitiator().initiateProactiveServer(
ASYNC_SERVER_PORT);
} catch (IOException e) {
e.printStackTrace();
}
// Sleep indefinitely since otherwise the JVM would terminate
while (true) {
try {
Thread.sleep(Long.MAX_VALUE);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
AcceptCompletionHandler.java
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousServerSocketChannel;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
public class AcceptCompletionHandler
implements
CompletionHandler<AsynchronousSocketChannel, SessionState> {
private AsynchronousServerSocketChannel listener;
public AcceptCompletionHandler(
AsynchronousServerSocketChannel listener) {
this.listener = listener;
}
#Override
public void completed(AsynchronousSocketChannel socketChannel,
SessionState sessionState) {
System.out.println("Accept Handler running on "+Thread.currentThread().getName());
// accept the next connection
SessionState newSessionState = new SessionState();
listener.accept(newSessionState, this);
// handle this connection
ByteBuffer inputBuffer = ByteBuffer.allocate(2048);
ReadCompletionHandler readCompletionHandler =
new ReadCompletionHandler(socketChannel, inputBuffer);
socketChannel.read(
inputBuffer, sessionState, readCompletionHandler);
}
#Override
public void failed(Throwable exc, SessionState sessionState) {
// Handle connection failure...
}
}
ReadCompletionHandler.java
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
public class ReadCompletionHandler implements
CompletionHandler<Integer, SessionState> {
private AsynchronousSocketChannel socketChannel;
private ByteBuffer inputBuffer;
public ReadCompletionHandler(
AsynchronousSocketChannel socketChannel,
ByteBuffer inputBuffer) {
this.socketChannel = socketChannel;
this.inputBuffer = inputBuffer;
}
#Override
public void completed(
Integer bytesRead, SessionState sessionState) {
System.out.println("Read Handler running on "+Thread.currentThread().getName());
byte[] buffer = new byte[bytesRead];
inputBuffer.rewind();
// Rewind the input buffer to read from the beginning
inputBuffer.get(buffer);
String message = new String(buffer);
// System.out.println("Received message from client : " + message);
// message = GetRequestParser.getHTTPRequest(message, "200 OK");
// Echo the message back to client
WriteCompletionHandler writeCompletionHandler =
new WriteCompletionHandler(socketChannel);
ByteBuffer outputBuffer = ByteBuffer.wrap(message.getBytes());
socketChannel.write(
outputBuffer, sessionState, writeCompletionHandler);
}
#Override
public void failed(Throwable exc, SessionState attachment) {
//Handle read failure.....
}
}
WriteCompletionHandler.java
import java.io.IOException;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
public class WriteCompletionHandler implements
CompletionHandler<Integer, SessionState> {
private AsynchronousSocketChannel socketChannel;
public WriteCompletionHandler(
AsynchronousSocketChannel socketChannel) {
this.socketChannel = socketChannel;
}
#Override
public void completed(
Integer bytesWritten, SessionState attachment) {
try {
System.out.println("Write Handler running on "+Thread.currentThread().getName());
System.out.println("\n");
socketChannel.close();
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void failed(Throwable exc, SessionState attachment) {
// Handle write failure.....
}
}
SessionState.java
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class SessionState {
private Map<String, String> sessionProps =
new ConcurrentHashMap<>();
public String getProperty(String key) {
return sessionProps.get(key);
}
public void setProperty(String key, String value) {
sessionProps.put(key, value);
}
}
In order to check the threading behaviour, I print the thread on which each handler runs to 'sys.out'.
Following are the different results I got, for many requests which are sent to the server one after the other.
Request 1
Accept Handler running on Thread-4
Read Handler running on Thread-4
Write Handler running on Thread-4
Request 2
Accept Handler running on Thread-4
Read Handler running on Thread-2
Write Handler running on Thread-2
Request 3
Accept Handler running on Thread-5
Read Handler running on Thread-3
Write Handler running on Thread-3
According to the above results, it seems like, for different requests, the server uses different threads. Also, both Read Handler and Write Handler are run on the same thread for a given request.
Can someone explain this result? As how handlers are scheduled on different threads?
As seen in your results for Thread.getCurrentThread().getName() for each Completion handler, in NIO2 (proactor pattern) the thread allocation for different Completion handlers is not specified and seems random. So, the best practice is not to assume any thread behaviour.
For the sake of completeness, I am adding the thread behaviour of NIO, in the following.
In NIO, each activity (be it socket accept, read or write) is run in a single thread (in which the selector loop runs.)

Java websocket client throws exception at send method (TooTallNate)

I got a Java project that is supposed to create a websocket client using TooTallNate. Everything seems to be working, connection is succesful to the websocket server but when I call the send method on the socket I get the following:
Exception in thread "Thread-1" org.java_websocket.exceptions.WebsocketNotConnectedException
at org.java_websocket.WebSocketImpl.send(WebSocketImpl.java:608)
at org.java_websocket.WebSocketImpl.send(WebSocketImpl.java:585)
at org.java_websocket.client.WebSocketClient.send(WebSocketClient.java:207)
at Main$2.run(Main.java:39)
at java.lang.Thread.run(Unknown Source)
opened connection
Connection is successfully opened but the send method throws the exception.
I got the following code:
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import org.java_websocket.client.WebSocketClient;
import org.java_websocket.handshake.ServerHandshake;
public class Main
{
public static void main(String[] args) throws InterruptedException
{
Queue<String> queue = new ConcurrentLinkedQueue<String>();
Runnable producer = new Runnable() {
#Override
public void run() {
for(int i = 0; i < 1000; i++) {
queue.offer(String.valueOf(i));
}
}
};
Thread producerThread = new Thread(producer);
producerThread.start();
Runnable consumer = new Runnable() {
#Override
public void run() {
wsClient c = null;
try {
c = new wsClient( new URI( "ws://echo.websocket.org") );
} catch (URISyntaxException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
c.connect();
c.send("hello");
while(true) {
String value = queue.poll();
if(value.equals("100")){
return;
}
System.out.println(value);
}
}
};
Thread consumerThread = new Thread(consumer);
consumerThread.start();
producerThread.join();
consumerThread.join();
}
}
Which simply creates a queue, adds data to it and then polls data from it while at the same time creating a websocket connection to a websocket server but as soon as I try to send data via the socket it throws the exception. Does someone know what could be the issue?
Here you have used connect() method, This is a non blocking method, which is starting the connection/handshake etc.
If you wanna send a frame right after connecting, please use the method connectBlocking() instead of connect().
connectBlocking() method blocks the thread till the connection is established
All credits go to https://github.com/TooTallNate/Java-WebSocket/issues/642

Java Android Sockets Threading

I've a client class which tries to connect to a server. But as you know you can't
execute network operations on the Main UI thread. So I've to create different threads for each operation.
Current code:
package com.example.justus.rocchat;
import android.os.AsyncTask;
import android.util.JsonWriter;
import java.io.BufferedWriter;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.URL;
import java.net.UnknownHostException;
/**
* Created by justus on 13-1-2015.
*/
public class Client
{
private String name;
private int port;
private String hostAddress;
private Socket socketClient;
private MainActivity mainActivity;
public boolean isConnected;
public Client(MainActivity mainActivity, String hostAdress, int port)
{
this.hostAddress = hostAdress;
this.port = port;
this.mainActivity = mainActivity;
}
public void send(final byte[] data)
{
Thread sendThread = new Thread(new Runnable() {
public void run()
{
try
{
DataOutputStream out = new DataOutputStream(socketClient.getOutputStream());
out.write(data);
System.out.println("writed data");
} catch (IOException ex) {
}
}
});
sendThread.start();
}
public void connect()
{
Thread connectThread = new Thread(new Runnable() {
public void run() {
try
{
System.out.println("trying to connect");
socketClient = new Socket(hostAddress, port);
isConnected = true;
}
catch(UnknownHostException ex)
{
System.out.println("ex:" + ex.getMessage());
}
catch (IOException ex)
{
System.out.println("ex:" + ex.getMessage());
}
}
});
connectThread.start();
}
}
Isn't this a little to much? Are there any better ways to handle this operations?
Already thanks for your time.
AsyncTask is the accepted way of handling asynchronous operations. It is a wrapper around the Thread class and is part of the Android SDK. They should only be used for operations that last under a few seconds, for longer operations you should use a Service.
developer.android.com/reference/android/os/AsyncTask.html
There are 2 options that you have
Use AsyncTask - much easier, object oriented that using threads but only for shortlived tasks (under 30 secs)
Use RoboSpice - https://github.com/stephanenicolas/robospice
Of the two, I prefer RoboSpice

Categories

Resources