I try to connected web socket in my android application for this http://192.168.0.6:8989/websocket URl but nothing get any response like error or success.
I am using stomp web-socket library but no success found.
'''// connectWebSocket();
// Create a WebSocket factory and set 5000 milliseconds as a timeout
// value for socket connection.
WebSocketFactory factory = new WebSocketFactory().setConnectionTimeout(5000);
// Create a WebSocket. The timeout value set above is used.
try {
ws =factory.createSocket("http://192.168.0.6:8989/websocket");
ws.addListener(new WebSocketAdapter() {
#Override
public void onTextMessage(WebSocket websocket, String message) throws Exception {
Log.d("TAG", "onTextMessage: " + message);
}
});
ws.connectAsynchronously();
} catch (IOException e) {
e.printStackTrace();
}'''
compile 'com.neovisionaries:nv-websocket-client:2.4'
Related
I have a client on a PC and a server on a tablet. I know the MAC addresses for both which means I do not do discoveries.
1. On the client if I use
connectString = "btspp://" + MACaddress + ":4;authenticate=false;encrypt=false;master=false";
It connects fine.
If I change the CN number (4) to anything else, it does not work. How is this number determined?
2. Everything works fine if the tablet is a Samsung with Android 5.0.2 When I use a Qunyico tablet with Android 10, it does not work. I get an error: Failed to connect; [10051] A socket operation was attempted to an unreachable network. What is the problem?
Client on PC – code taken from “Bluetooth-java-client-master”
public class IrcBluetoothClient {
private static void openConnection(String MACaddress) throws IOException {
// Tries to open the connection.
String connectString = "btspp://" + MACaddress + ":4;authenticate=false;encrypt=false;master=false";
StreamConnection connection = (StreamConnection) Connector.open(connectString);
if (connection == null) {
System.err.println("Could not open connection to address: " + MACaddress);
System.exit(1);
}
// Initializes the streams.
OutputStream output = connection.openOutputStream();
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader reader = new BufferedReader(isr);
// Starts the listening service for incoming messages.
ExecutorService service = Executors.newSingleThreadExecutor();
service.submit(new IncomingMessagesLoggingRunnable(connection));
// Main loop of the program which is not complete yet
LocalDevice localDevice = LocalDevice.getLocalDevice();
while (true) {
String toSend = reader.readLine();
byte[] toSendBytes = toSend.getBytes(StandardCharsets.US_ASCII);
output.write(toSendBytes);
System.out.println("[" + localDevice.getFriendlyName() + " - " +
localDevice.getBluetoothAddress() + "]: " + toSend);
System.exit(1);
}
Server on tablet – code taken from https://developer.android.com/guide/topics/connectivity/bluetooth
private static final UUID A_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
public BTacceptConnections( BluetoothAdapter mBluetoothAdapter) {
// Use a temporary object that is later assigned to mmServerSocket
// because mmServerSocket is final.
BluetoothServerSocket tmp = null;
try {
// A_UUID is the app's UUID string, also used by the client code.
tmp = mBluetoothAdapter.listenUsingRfcommWithServiceRecord(NAME, A_UUID);
} catch (IOException e) {
Log.e(TAG, "Socket's listen() method failed", e);
}
mmServerSocket = tmp;
// Closes the connect socket and causes the thread to finish.
public void cancel(){
try {
mmServerSocket.close();
}catch (IOException e){
}
runFlag = 1;
}
//***********************************************************************************************
//
// This thread runs all the time listening for incoming connections.
//
public void run() {
BluetoothSocket socket = null;
// Keep listening until exception occurs or a socket is returned.
while (runFlag == 0) {
try {
socket = mmServerSocket.accept();
} catch (IOException e) {
Log.e(TAG, "Socket's accept() method failed", e);
break;
}
if (socket != null) { // If a connection was accepted
// A connection was accepted. Perform work associated with
// the connection in a separate thread.
// manageMyConnectedSocket(socket);
}else{
try {
mmServerSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
break;
}
}
I know the MAC addresses for both which means I do not do discoveries.
Official Linux Bluetooth protocol stack BlueZ uses D-BUS API to establish bluetooth communication. If you check adapter-api, scanning will create device objects that you need to establish a communication which means discovering is not only done to retrieve MAC addresses only.
Your case might be the same, I would suggest doing discovery first.
I'm currently runing a server on Eclipse(local IP 192.168.1.255, listening to port 4567). A client can connect trought sockets and send messages, that will be printed on the terminal by the server.
Part of the server code is the following:
System.out.println("Client connected: " + clientName);
String line;
while (true){
line = in.nextLine();
System.out.println("STRING RECEIVED: " + line + " FROM " + clientName);
}
where in is the input stream of the client socket.
Part of client code, instead, is:
while(true) {
System.out.print("\nEnter your input: ");
line = stdin.next();
socketOut.println(line);
socketOut.flush();
}
So, in example, a possible output on server terminal with two clients connected is the following:
Client connected: Socket[addr=/192.168.1.225,port=54852,localport=4567]
STRING RECEIVED: Hello FROM Socket[addr=/192.168.1.225,port=54852,localport=4567]
STRING RECEIVED: World FROM Socket[addr=/192.168.1.225,port=54852,localport=4567]
Client connected: Socket[addr=/192.168.1.225,port=54945,localport=4567]
STRING RECEIVED: Hello2 FROM Socket[addr=/192.168.1.225,port=54945,localport=4567]
Everything works well, so i'm now trying to access server trough sockets on a simple app developed on Android Studio. The code is:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new BackgroundTask().execute();
}
private class BackgroundTask extends AsyncTask {
#Override
protected Object doInBackground(Object[] params) {
try {
Socket socket = new Socket("10.0.2.2", 4567);
PrintWriter out = new PrintWriter(socket.getOutputStream());
out.println(new String("Hi from Android!"));
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
}
But the output is just
Client connected: Socket[addr=/192.168.1.225,port=55001,localport=4567]
and nothing else.
Any advice about the println doesn't send anything? The program works perfectly on Eclipse on both client/server side, so i guess the problem is on Android. Also, i enabled the Android network permissions, so the connection should work.
Thanks in advance to everybody.
EDIT: solved, i just changed Android client code to:
try {
Socket socket = new Socket("10.0.2.2", 4567);
if (socket.isConnected()) {
PrintWriter out = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(socket.getOutputStream())), true);
String line = new String("Hi from Android!");
out.println(line);
}
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
You need to either flush the PrintWriter or construct it to auto-flush. It doesn't by default.
Im trying use use an AMQP message queue in one of my Android applications. I tested the code first in a java application and have no issues but when I put the same code into an Android app no error is thrown but the AMQP channel closes unexpectedly after the first message is received. I tried adding a shutdown listener to the channel but it didnt return anything. Can someone help me figure out why the Rabbitmq channel is closing?
// ------------------------------------------------------------------------
// Function to make AMQP connection and subscribe
// ------------------------------------------------------------------------
int connAmqp()
{
factory = new ConnectionFactory();
factory.setHost(PI_AMQP_BROKER_URL);
factory.setUsername(AMQP_BROKER_USERNAME);
factory.setPassword(AMQP_BROKER_PASSWORD);
factory.setPort(AMQP_BROKER_PORT);
connection=null;
connectionStatus = AMQP_CONNECTING;
try {
connection = factory.newConnection();
Log.i("log_amqp_conn","Successfully connected to AMQP broker");
connectionStatus = AMQP_CONNECTED;
channel = connection.createChannel();
channel.addShutdownListener(new ShutdownListener() {
#Override
public void shutdownCompleted(ShutdownSignalException cause) {
Log.w("log_amqp_shutdown",cause.getCause().toString());
}
});
channel.exchangeDeclare(AMQP_EXCHANGE_NAME, "topic");
Log.i("log_amqp_conn","Successfully connected to Exchange: " + AMQP_EXCHANGE_NAME);
channel.queueDeclare(RX_QUEUE_NAME, false, false, false, null);
String queueBind = RX_BINDING;
Log.i("log_amqp_conn","Successfully declared queue: " + RX_QUEUE_NAME);
channel.queueBind(RX_QUEUE_NAME, AMQP_EXCHANGE_NAME, queueBind);
Log.i("log_amqp_conn","Successfully binding to: " + queueBind);
} catch (TimeoutException e) {
Log.i("log_amqp_conn","Connection timeount - Failed to connect to AMQP broker");
Log.i("log_amqp_conn",e.toString());
connectionStatus = AMQP_NOTCONNECTED_TIMEOUT;
} catch (IOException e) {
Log.i("log_amqp_conn","Failed to connect to AMQP broker");
Log.i("log_amqp_conn",e.toString());
connectionStatus = AMQP_NOTCONNECTED_UNKNOWNREASON;
}catch (Exception e) {
Log.i("log_amqp_conn","Failed to connect to AMQP broker");
Log.i("log_amqp_conn",e.toString());
connectionStatus = AMQP_NOTCONNECTED_UNKNOWNREASON;
}
Log.i("log_amqp_conn"," [*] Waiting for messages.");
consumer = new DefaultConsumer(channel) {
#Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body)
throws IOException {
Log.i("log_amqp_conn", "handleDelivery() called");
String message = new String(body, "UTF-8");
Log.i("log_amqp_conn"," [Rx] Received: " + message);
//DO SOME WORK HERE
}
};
try {
Log.i("log_amqp_conn", "basicConsume() called");
channel.basicConsume(RX_QUEUE_NAME, true, consumer);
} catch (IOException e) {
Log.e("log_amqp_consume",e.toString());
}
return 0;
}
After spending much time looking in the wrong places I found that the channel was closing due to an unhandled exception in the handleDelivery() function in the "//DO SOME WORK HERE" code. Turns out that if this method errors out that the AMQP channel will close. Thanks.
I need to implement a TCP comunication between an IoT device(custom) and an Android App.
For the Wifi device we have a Server Socket, while in Android i have an AsyncTask as a Client Socket. Both the device and the smarthone are connected to the same network.
Here is the Android Client Socket code for the initialization/socket-read and socket-write:
Variables:
static public Socket nsocket; //Network Socket
static public DataInputStream nis; //Network Input Stream
static private OutputStream nos; //Network Output Stream
AsyncTask method doInBackgroud:
#Override
protected Boolean doInBackground(Void... params) { //This runs on a different thread
boolean result = false;
try {
//Init/Create Socket
SocketInit(IP, PORT);
// Socket Manager
SocketUpdate();
} catch (IOException e) {
e.printStackTrace();
Log.i("AsyncTask", "doInBackground: IOException");
clearCmdInStack();
MainActivity.SocketDisconnectAndNetworkTaskRestart();
result = true;
} catch (Exception e) {
e.printStackTrace();
Log.i("AsyncTask", "doInBackground: Exception");
result = true;
} finally {
try {
SocketDisconnect();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
Log.i("AsyncTask", "doInBackground: Finished");
}
return result;
}
Socket Initializzation:
public void SocketInit(String ip, int port) throws IOException {
InetAddress addr = InetAddress.getByName(ip);
SocketAddress sockaddr = new InetSocketAddress(addr, port);
nsocket = new Socket();
nsocket.setReuseAddress(false);
nsocket.setTcpNoDelay(true);
nsocket.setKeepAlive(true);
nsocket.setSoTimeout(0);
nsocket.connect(sockaddr, 0);
StartInputStream();
StartOutputStream();
}
Read from Socket:
private void SocketUpdate() throws IOException, ClassNotFoundException {
int read = 0;
// If connected Start read
if (socketSingleton.isSocketConnected()) {
// Print "Connected!" to UI
setPublishType(Publish.CONNECTED);
publishProgress();
if(mConnectingProgressDialog != null)
mConnectingProgressDialog.dismiss(); //End Connecting Progress Dialog Bar
//Set Communications Up
setCommunicationsUp(true);
Log.i("AsyncTask", "doInBackground: Socket created, streams assigned");
Log.i("AsyncTask", "doInBackground: Waiting for inital data...");
byte[] buffer = new byte[3];
do{
nis.readFully(buffer, 0, 3);
setPublishType(Publish.READ);
publishProgress(buffer);
}while(!isCancelled());
SocketDisconnect();
}
}
Streams init:
public void StartInputStream() throws IOException{
nis = new DataInputStream(nsocket.getInputStream());
}
public void StartOutputStream() throws IOException{
nos = nsocket.getOutputStream();
}
Read and Write methods:
public int Read(byte[] b, int off, int len) throws IOException{
return nis.read(b, off, len); //This is blocking
}
public void Write(byte b[]) throws IOException {
nos.write(b);
nos.flush();
}
public boolean sendDataToNetwork(final String cmd)
{
if (isSocketConnected())
{
Log.i("AsyncTask", "SendDataToNetwork: Writing message to socket");
new Thread(new Runnable()
{
public void run()
{
try
{
Write(cmd.getBytes());
}
catch (Exception e)
{
e.printStackTrace();
Log.i("AsyncTask", "SendDataToNetwork: Message send failed. Caught an exception");
}
}
}).start();
return true;
}
Log.i("AsyncTask", "SendDataToNetwork: Cannot send message. Socket is closed");
return false;
}
The application is very simple, the android app sends a command(via sendDataToNetwork method) to the IoT device and the latter sends back an "ACK" Command string.
The problem
The problem is that while the IoT device always receives the command, the smartphone rarely gets the ACK back. Sometimes i get something like "ACKACKACKACK". By debugging the IoT device i'm sure that it successfully sends back the ACK, so the problem lies in the InputStream read() method which doesn't retrieve the string right away.
Is there a way to empty the InputStream buffer right away, so that i get an "ACK" string back from the IoT device every time i send a command?
Update
I've updated the socket config so that there are no more buffer limitations and i've replaced read() method with readFully. It greatly improved, but still make some mistakes. For istance one out of 2-3 times no ack is received and i get 2 ack the next turn. Is this perhaps the computational limit of the IoT device? Or is there still margin for a better approach?
the problem lies in the InputStream read() method which doesn't empty the buffer right away.
I don't know what 'empty the buffer' means here, but InputStream.read() is specified to return as soon as even one byte has been transferred.
Is there a way to empty the InputStream buffer right away, so that i get an "ACK" string back from the IoT device every time i send a command?
The actual problem is that you could be reading more than one ACK at a time. And there are others.
If you're trying to read exactly three bytes, you should be using DataInputStream.readFully() with a byte array of three bytes.
This will also get rid of the need for the following array copy.
You should not mess with the socket buffer sizes except to increase them. 20 and 700 are both ridiculously small values, and will not be the actual values used, as the platform can adjust the value supplied. Your claim that this improved things isn't credible.
You should not spin-loop while available() is zero. This is literally a waste of time. Your comment says you are blocked in the following read call. You aren't, although you should be. You are spinning here. Remove this.
I try to create a Simple TCP Server on Android phone and waiting for client.
I only want to implement the connection between TCPServer and Client , it doesn't need to transmit any data.
I have the another application for client , It use to connect to this TCPServer.
The code of TCPServerthread is like the following.
private class TCPServerThread implements Runnable
{
#Override
public void run() {
// TODO Auto-generated method stub
try {
ServerSocket serverSocket = new ServerSocket(PORT);
//while loop
while (true) {
Log.i(TAG, "TCPServerThread...while loop");
try {
Socket socket = serverSocket.accept();
Log.i(TAG, "TCPServerThread...socket.getInetAddress() = " + socket.getInetAddress());
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
Log.i(TAG, "First IOException");
}
}
//while loop end
} catch (Exception e) {
// TODO: handle exception
//e.printStackTrace();
Log.i(TAG, "Second IOException");
}
}
}
But it seems stop at Socket socket = serverSocket.accept(); and doesn't show the log of TCPServerThread...socket.getInetAddress() = when the client try to connect to this Server.
DO I missing something for TCPServer ?
Is it mean the client doesn't connect to the Server when the code stop at Socket socket = serverSocket.accept(); ??
----------------------------EDIT----------------------------------------
Update the process.
The Server(Android Phone) open the WiFi-Hot-Spot, it also open the TCP-Server like the above code.
After Client connect to WiFi-Hot-Spot , the Client and the Server are in the same network.
The Client will get a IP address of gateway, and the Client try to connect to this IP address of gateway by TCP.
So the connection port and Server address seems correct for Client.
Your code is correct, but it seems that no one is connecting to your TCPserver.
To avoid this blocking situation on
Socket socket = serverSocket.accept();
you have to set the timeout option for your socket when you declare it
serverSocket.setSoTimeout(mTime);
;)