EDIT:
I want to implement a quiz-application on Android and Browser via Web Interface.
I'm looking for a way to communicate between the server and the clients. I tried socket.io but couldn't get it working with android.
I'm using a node.js server hosted on nodester (nodester.com).
I tried some libs but couldn't get it working.
I'm now working with einaros/ws from https://github.com/einaros/ws
The server code is:
var clients = [],
numClients = 0;
var WebSocketServer = require('ws').Server,
wss = new WebSocketServer({port: 20083});
wss.on('connection', function(ws) {
ws.on('message', function(message) {
console.log(wss.clients);
console.log('received: %s', message);
incomingMessage(message, ws)
});
/*
ws.on('eigenesEvent', function(message) {
console.log('eigenes Event ausgelöst: ' + message);
});
*/
});
function incomingMessage(msg, ws) {
//console.log(wss.clients);
var obj = JSON.parse(msg);
if(obj.type == "connect") {
for(var i=0;i<clients.length;i++) {
if(clients[i] == obj.id) {
ws.send(JSON.stringify({
to: obj.id,
message: "name vergeben"
}));
return;
}
}
clients[numClients] = obj.id;
numClients++;
for(var i=0;i<clients.length;i++) {
console.log("Client" + i + ": " + clients[i]);
}
ws.send(JSON.stringify({
to: "all",
message: obj.id + " connected"
}));
}
if(obj.type == "disconnect") {
for(var i=0;i<clients.length;i++) {
if(clients[i] == obj.id) {
clients.splice(i, 1);
numClients--;
for(var i=0;i<clients.length;i++) {
console.log("Client" + i + ": " + clients[i]);
}
}
}
ws.send(JSON.stringify({
to: "all",
message: obj.id + " disconnected"
}));
return;
}
if(obj.type == "answer") {
if("id" in obj) {
if(obj.answer == "a") {
ws.send(JSON.stringify({
to: obj.id,
message: "a is correct"
}));
} else {
ws.send(JSON.stringify({
to: obj.id,
message: "answer is incorrect"
}));
}
}
}
if(obj.type == "something") {
if("id" in obj) {
ws.send(JSON.stringify({
to: obj.id,
message: "received: " + obj.message
}));
}
}
}
From a HTML-Site i can connect to the server via:
connect = function() {
var host = "ws://einaros.nodester.com";
try{
socket = new WebSocket(host);
console.log('WebSocket - status ' + socket.readyState);
socket.onopen = function(msg) {
console.log("Welcome - status " + this.readyState);
socket.send(JSON.stringify({
id: model.getClientName(),
type: "connect"
}));
model.setConnectionStatus(true);
};
socket.onmessage = function(msg) {
console.log("onmessage - msg: " + msg.data);
checkMessage(msg.data);
};
socket.onclose = function(msg) {
console.log("Disconnected - status " + this.readyState);
model.setConnectionStatus(false);
};
}
catch(ex){
console.log(ex);
}
},
On the Android-Client side i'm using AutobahnAndroid from: http://autobahn.ws/android
The client code for android is:
package ps.mediengestaltung;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import de.tavendo.autobahn.WebSocketConnection;
import de.tavendo.autobahn.WebSocketException;
import de.tavendo.autobahn.WebSocketHandler;
public class MainActivity extends Activity {
public final WebSocketConnection mConnection = new WebSocketConnection();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final String wsuri = "ws://einaros.nodester.com";
try {
mConnection.connect(wsuri, new WebSocketHandler() {
#Override
public void onOpen() {
Log.d("TAG", "Status: Connected to " + wsuri);
mConnection.sendTextMessage("Hello Server!");
}
#Override
public void onTextMessage(String payload) {
Log.d("TAG", "Got echo: " + payload);
}
#Override
public void onClose(int code, String reason) {
Log.d("TAG", "Connection lost.");
}
});
} catch (WebSocketException e) {
Log.d("TAG", e.toString());
}
}
}
In LogCat i get:
08-01 08:48:13.017: D/TAG(704): Status: Connected to ws://einaros.nodester.com
08-01 08:48:13.167: D/TAG(704): Connection lost.
What am i doing wrong? Any hints?
The reason could be: Weberknecht only implements the (outdated) Hixie-76 version of WebSocket.
You might try AutobahnAndroid, which implements the final RFC6455 version of WebSocket.
Another things: the WebSocket server you are using is no longer maintained (as far as I know). It also only implements Hixie-76 - which is no longer supported by Chrome/Firefox.
Try one of these:
https://github.com/einaros/ws
https://github.com/Worlize/WebSocket-Node
Disclaimer: I am the author of Autobahn and work for Tavendo.
You are asking your phone to connect to the localhost. You aren't running node on the phone right? :)
URI url = new URI("ws://127.0.0.1:8080/test");
This should instead be pointing to your nodester address/port.
Related
Now i'm try to connect with other device using samsung S6 Lite. Here i have a problem while connecting to the other device it's trying to connect and after few second it's OnClose method will call in my web socket listener.
I have tried on same thing in Samsung S7, Samsung S5 and emulator it's working fine. Only i got the connection issue in Samsung S6(OS: Android 11).
Node.js
const http = require('http');
const WebSocketServer = require('websocket').server;
const server = http.createServer();
server.listen(8080);
const wsServer = new WebSocketServer({
httpServer: server
});
wsServer.on('request', function(request) {
const connection = request.accept(null, request.origin);
console.log('Server Connected')
connection.on('message', function(message) {
console.log('Received Message:', message.utf8Data);
//connection.sendUTF('Hi this is WebSocket server!');
connection.sendUTF('Socket server conne');
});
connection.on('close', function(reasonCode, description) {
console.log('Client has disconnected.',description.utf8Data);
});
connection.on('error', function(error){
console.log('Client has error',error.utf8Data);
});
connection.on('frame', function(frame){
console.log('Client has frame');
});
});
wsServer.on('connect',function(connection){
console.log('Server connection status: ');
connection.on('message', function(message){
console.log('Server Received Message:', message.utf8Data);
});
});
Android Connection Code:
public void test() {
try {
URI uri;
try {
uri = new URI("ws://localhost:8080/test");
} catch (URISyntaxException e) {
e.printStackTrace();
return;
}
String myAndroidDeviceId = Settings.Secure.getString(getApplicationContext().getContentResolver(), ANDROID_ID);
Map<String, String> stringStringMap = new HashMap<>();
stringStringMap.put("device", "device," + myAndroidDeviceId);
String temp[] = {"device:device"};
cc = new WebSocketClient(uri) {
#Override
public void onOpen(ServerHandshake serverHandshake) {
String str = android.os.Build.MODEL;
String record = "Device Name : " + str;
// cc.send(String.valueOf(record));
cc.send(record);
System.out.println("Address" + cc.getRemoteSocketAddress());
Log.i("Websocket", "Opened");
System.out.println("SocketIPAddress--->Opened--->");
}
#Override
public void onMessage(String s) {
final String message = s;
System.out.println(message);
System.out.println("SocketIPAddress--->onMessage--->" + s);
updateUI(message);
}
#Override
public void onClose(int i, String s, boolean b) {
// Log.i("Websocket", "Closed " + s);
System.out.println("SocketIPAddress--->onClose--->" + s);
//updateUI("Disconnected");
}
#Override
public void onError(final Exception e) {
System.out.println("SocketIPAddress--->onError--->" + e.getMessage());
}
};
cc.connect();
} catch (Exception ex) {
Log.i("ErrorMsg", ex.getMessage());
}
}
Any one please help to fix this issue. Thanks
I have been struggling with what I believe is a screen repainting problem for a RecylerView when my underlying model is modified by another Thread. But have run out of ideas.
My application receives messages from a MQTT topic and displays it in a RecyclerView as a sort of "history" or "log" display.
This works fine as long as the MQTT session does not auto reconnect.
Once the MQTT session reconnects after a dropped connection, I still receive messages from the MQTT topic, the messages are still added to my model, I still raise the "Data changed" notification, I still invalidate the RecyclerView control, but the RecyclerView is no longer repainted to reveal the new message on screen.
If I manually force a refresh/repaint of the screen (e.g. scroll the recycler view, switch to another app and back again etc) then the RecyclerView is repainted and shows the "missing" messages.
My question is: what is it about the RecyclerView that seems to be causing it to not repaint when the underlying model is modified as a result of messages being received from an MQTT topic, but only if the MQTT session is dropped and reconnected?????
And obviously, what do I need to do to fix it?????
Update
I've tried adding the following method (which is activated by the onClick of a Floating button).
public void buttonClick (View v) {
mAdapter.add("Button Message");
Toast.makeText(getApplicationContext(),"Button message added", Toast.LENGTH_SHORT).show();
}
This method suffers from the same problem as messages received from the MQTT topic. If I click it before the MQTT auto-reconnect, the "Button Message" is added to my RecyclerView and displayed.
Once MQTT session is dropped and then auto reconnected, even this "buttonClick" method's "Button Message" is no longer displayed unless I force a refresh of the RecyclerList. FWIW, the "Toast" is always displayed (before and after the MQTT autoreconnect).
Could it be that I've stumbled upon some sort of wierd bug in RecyclerView???
FWIW 1, I've read many posts trying to get RecyclerView to work in relation to background thread updates of the underlying data model. Some suggest running the notification on the MainUI thread. I believe that this does make a difference. Previously it never displayed any of the messages received from the MQTT topic, now it does - but not if the connection is lost and reconnected.
FWIW 2, I know that the notifyDataSetChanged should be used as a last resort as it is least efficient. I have tried some of the other notify methods. These other notification methods produce the exact same problem as notifyDataSetChanged. At this point I am trying to keep it simple, so as to get it to work. Next I can focus on efficiency.
Here are the relevant code snippets.
Firstly, the MQTT callback which is invoked when a message is received:
#Override
public void messageArrived(final String topic, MqttMessage message) throws Exception {
final String msg = new String(message.getPayload());
if ("glennm/test/temp".equals(topic)) {
Log.i("RCVD", "Temperature: " + msg); // This code is shown to illustrate a control that
if (textViewTemperature != null) { // always seems to be redisplayed when a message is received
textViewTemperature.setText(msg + "°"); // even if the connection is lost and reconnected
textViewTemperature.invalidate();
temperatureHistory.add(msg);
temperatureHistory.dump("TEMP");
} else {
Log.e("NULL", "textView temperature control is null");
}
} else if ("glennm/test/humid".equals(topic)) {
// Code that updates the humidity text view omitted for brevity (as it is basically the same as the temperature code above.
} else { /***** This is the problem area - other messages logged to the Recycler view ****/
String wrk = topic;
if (topic != null && topic.toLowerCase().startsWith("glennm/test")) {
wrk = topic.substring(12);
}
final String topicToShow = wrk;
textViewOtherTopic.setText(topicToShow);
textViewOtherMessage.setText(msg);
// mAdapter.add(topicToShow + ": " + msg);
// The notify that the add method calls ***MUST*** be run on the main UI thread.
// Failure to do so means that the call will sometimes be ignored and the
// Recycler view is not updated to show the new incoming value.
// https://stackoverflow.com/questions/36467236/notifydatasetchanged-recyclerview-is-it-an-asynchronous-call/36512407#36512407
// This seems to help, but we still seem to have the same behaviour if the MQTT connection resets.
runOnUiThread(new Runnable() {
// recyclerView.post(new Runnable() {
#Override
public void run() {
mAdapter.add(topicToShow + ": " + msg);
recyclerView.invalidate();
}
});
Log.i("RCVD", "Other Topic: " + topic + ", message: " + msg);
}
}
}
Secondly, the code that is invoked to add the message to the underlying data model (and notify the UI to repaint it).
public void add(String msg) {
Log.d("HISTORY", "Adding message: " + msg);
messageList.add(msg);
while (messageList.size() > MAX_HISTORY) {
messageList.remove(0);
}
Log.d("HISTORY", "Notifying data set changed");
_parent.runOnUiThread(new Runnable () {
#Override
public void run() {
notifyDataSetChanged();
}
});
Log.d("HISTORY", "Notifying data set changed - complete");
}
Finally, here are three screen snapshots which try to illustrate the problem. In the first, messages have been received from the MQTT topic and are displayed both in the journal and the "current message" field (textViewOtherTopic and textViewOtherMessage controls) located below the humidity.
What happens between the first and second screen shot is that the MQTT service lost its connection and auto-reconnected. After that, the received message is only displayed in the "current message" view and not the "message log" recycler view (despite being added to the model).
Only when the Recycler View is forced to be repainted by an external (manual) user action (e.g. scrolling) does the missing message(s) show up.
Here is an example of a command using the mosquitto mqtt client that is used to post a message to the app:
mosquitto_pub -h test.mosquitto.org -t "glennm/test/comment" -q 1 -m "It's a new day, but still cold! 3"
Following is the full code for the two classes (including many of the commented out attempts I've made)...
The Main activity:
package com.gtajb.tempmonitorapp;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
import org.eclipse.paho.android.service.MqttAndroidClient;
import org.eclipse.paho.client.mqttv3.DisconnectedBufferOptions;
import org.eclipse.paho.client.mqttv3.IMqttActionListener;
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.IMqttMessageListener;
import org.eclipse.paho.client.mqttv3.IMqttToken;
import org.eclipse.paho.client.mqttv3.MqttCallbackExtended;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import java.util.ArrayList;
import java.util.UUID;
public class MainActivity extends AppCompatActivity {
private MqttAndroidClient mqttAndroidClient;
private String serverUri = "tcp://test.mosquitto.org:1883";
public static final String clientId = UUID.randomUUID().toString();
public final String subscriptionTopic = "glennm/test/#";
public final String publishTopic = "glennm/test/tome";
public final String publishMessage = "Hello from Android test client";
private TextView textViewTemperature;
private TextView textViewHumidity;
private TextView textViewOtherTopic;
private TextView textViewOtherMessage;
private MessageCallBack messageCallBack = new MessageCallBack();
private RecyclerView recyclerView;
private MessageHistory mAdapter;
private RecyclerView.LayoutManager layoutManager;
private ReadingsHistory temperatureHistory = new ReadingsHistory();
private ReadingsHistory humidityHistory = new ReadingsHistory();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d("INFO", "Createing the mqtt client with client ID: " + clientId);
mqttAndroidClient = new MqttAndroidClient(getApplicationContext(), serverUri, clientId);
mqttAndroidClient.setCallback(new MqttClientCallback());
MqttConnectOptions mqttConnectOptions = new MqttConnectOptions();
mqttConnectOptions.setAutomaticReconnect(true);
mqttConnectOptions.setCleanSession(false);
textViewTemperature = findViewById(R.id.temperatureValueLabel);
textViewTemperature.setText("Temp goes here");
textViewHumidity = findViewById(R.id.humidtyValueLabel);
textViewHumidity.setText("Humid goes here");
textViewOtherTopic = findViewById(R.id.otherTopicValueLabel);
textViewOtherMessage = findViewById(R.id.otherMessageValueLabel);
textViewOtherTopic.setText(".");
textViewOtherMessage.setText(".");
recyclerView = findViewById(R.id.historyPanel);
mAdapter = new MessageHistory(new ArrayList<String>(), this, recyclerView);
layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(mAdapter);
mAdapter.add("A test message");
messageCallBack = new MessageCallBack();
try {
mqttAndroidClient.connect(mqttConnectOptions, null, new IMqttActionListener() {
#Override
public void onSuccess(IMqttToken asyncActionToken) {
DisconnectedBufferOptions disconnectedBufferOptions = new DisconnectedBufferOptions();
disconnectedBufferOptions.setBufferEnabled(true);
disconnectedBufferOptions.setBufferSize(100);
disconnectedBufferOptions.setPersistBuffer(false);
disconnectedBufferOptions.setDeleteOldestMessages(false);
mqttAndroidClient.setBufferOpts(disconnectedBufferOptions);
//subscribeToTopic();
}
#Override
public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
Log.e("CONNECT", "Failed to connect to " + serverUri);
Log.e("CONNECT", exception.getMessage());
}
});
} catch (MqttException e) {
Log.e("CONNECT", "Exception connecting to " + serverUri);
Log.e("CONNECT", e.getMessage());
Log.e("CONNECT", Log.getStackTraceString(e));
e.printStackTrace();
}
}
#Override
protected void onDestroy() {
super.onDestroy();
Log.i("CONN", "Closing MQTT connection");
mqttAndroidClient.close();
}
public class MqttClientCallback implements MqttCallbackExtended {
#Override
public void connectComplete(boolean reconnect, String serverURI) {
if (reconnect) {
Log.i("CONN", "Reconnected to: " + serverURI);
subscribeToTopic();
} else {
Log.i("CONN", "Connected to: " + serverURI);
subscribeToTopic();
}
}
#Override
public void connectionLost(Throwable cause) {
Log.i("CONN", "Connection lost");
}
#Override
public void messageArrived(String topic, MqttMessage message) throws Exception {
Log.i("MSG", topic + " - " + new String(message.getPayload()));
}
#Override
public void deliveryComplete(IMqttDeliveryToken token) {
Log.i("PUB", "Delivery complete");
}
}
public void subscribeToTopic() {
try {
Log.i("TOPIC", "Subscribing to: " + subscriptionTopic);
// mqttAndroidClient.subscribe(subscriptionTopic, 0, null, new IMqttActionListener() {
// #Override
// public void onSuccess(IMqttToken asyncActionToken) {
// Log.i("SUBS", "Subscription to " + subscriptionTopic + " on " + serverUri + " successful");
// }
//
// #Override
// public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
// Log.i("SUBS", "Subscription to " + subscriptionTopic + " on " + serverUri + " FAILED");
// }
// });
mqttAndroidClient.subscribe(subscriptionTopic, 0, messageCallBack);
} catch (MqttException e) {
Log.e("SUBS", "Failed to subscribe to topic: " + subscriptionTopic + " on " + serverUri);
Log.e("SUBS", e.getMessage());
}
}
public void setTemperatureValue(String val) {
textViewTemperature.setText(val);
}
public void setHumidityValue(String val) {
textViewHumidity.setText(val);
}
public class MessageCallBack implements IMqttMessageListener , IMqttActionListener {
#Override
public void onSuccess(IMqttToken asyncActionToken) {
Log.i("MQTT", "Successful operation " + asyncActionToken.toString());
textViewTemperature.setText("Subscribed");
}
#Override
public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
Log.i("MQTT", "Un Successful operation + " + asyncActionToken.toString());
textViewTemperature.setText("Not Subscribed");
}
#Override
public void messageArrived(final String topic, MqttMessage message) throws Exception {
final String msg = new String(message.getPayload());
if ("glennm/test/temp".equals(topic)) {
Log.i("RCVD", "Temperature: " + msg);
if (textViewTemperature != null) {
textViewTemperature.setText(msg + "°");
textViewTemperature.invalidate();
temperatureHistory.add(msg);
temperatureHistory.dump("TEMP");
} else {
Log.e("NULL", "textView temperature control is null");
}
} else if ("glennm/test/humid".equals(topic)) {
Log.i("RCVD", "Humidity: " + msg);
textViewHumidity.setText(msg + "%");
textViewHumidity.invalidate();
humidityHistory.add(msg);
humidityHistory.dump("HUMID");
} else {
String wrk = topic;
if (topic != null && topic.toLowerCase().startsWith("glennm/test")) {
wrk = topic.substring(12);
}
final String topicToShow = wrk;
textViewOtherTopic.setText(topicToShow);
textViewOtherMessage.setText(msg);
// mAdapter.add(topicToShow + ": " + msg);
// The notify that the add method calls ***MUST*** be run on the main UI thread.
// Failure to do so means that the call will sometimes be ignored and the
// Recycler view is not updated to show the new incoming value.
// https://stackoverflow.com/questions/36467236/notifydatasetchanged-recyclerview-is-it-an-asynchronous-call/36512407#36512407
// This seems to help, but we still seem to have the same behaviour.
runOnUiThread(new Runnable() {
// recyclerView.post(new Runnable() {
#Override
public void run() {
mAdapter.add(topicToShow + ": " + msg);
// recyclerView.invalidate();
}
});
Log.i("RCVD", "Other Topic: " + topic + ", message: " + msg);
// Context context = getApplicationContext();
// Toast msgPopup = Toast.makeText(context, msg, Toast.LENGTH_SHORT);
// msgPopup.show();
}
}
}
}
The Message History class:
package com.gtajb.tempmonitorapp;
import android.app.Activity;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
public class MessageHistory extends RecyclerView.Adapter<MessageHistory.Callback> {
private ArrayList<String> messageList = new ArrayList();
public static final int MAX_HISTORY = 100;
private Activity _parent;
private RecyclerView rv;
public class Callback extends RecyclerView.ViewHolder {
TextView mTextView;
Callback(View itemView) {
super(itemView);
mTextView = itemView.findViewById(R.id.row_text);
}
}
public MessageHistory(ArrayList<String> messageList, Activity parent, RecyclerView rv) {
super();
this.messageList = messageList;
this._parent = parent;
this.rv = rv;
add("Test Message 1");
add("Test Message 2");
}
#NonNull
#Override
public Callback onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.history_row, parent, false);
return new Callback(v);
}
#Override
public void onBindViewHolder(#NonNull Callback holder, int position) {
Log.d("HISTORY", "Setting " + position + ": " + messageList.get(position));
holder.mTextView.setText(messageList.get(position));
}
#Override
public int getItemCount() {
Log.d("HISTORY", "Message Count: " + messageList.size());
return messageList.size();
}
/**
* Add a message to the message log.
* #param msg the message to add.
*/
public void add(String msg) {
Log.d("HISTORY", "Adding message: " + msg);
messageList.add(msg);
while (messageList.size() > MAX_HISTORY) {
messageList.remove(0);
}
// getItemCount();
Log.d("HISTORY", "Notifying data set changed");
_parent.runOnUiThread(new Runnable () {
#Override
public void run() {
notifyDataSetChanged();
}
});
//this.notifyDataSetChanged();
Log.d("HISTORY", "Notifying data set changed - complete");
// rv.invalidate();
// rv.refreshDrawableState();
// this.notifyItemInserted(messageList.size());
// final RecyclerView.Adapter adapter = this;
// _parent.runOnUiThread(new Runnable() {
// #Override
// public void run() {
// adapter.notifyDataSetChanged();
// }
// });
}
}
I wrote this node.js server which receives data from android client .But i tried to display the data in html page i could not display and i don't have any idea how to display in html page since am a beginner in nodejs. I just started to explore to get count of active users in realtime.
my nodejs server.js code
var net = require('net');
var sockets = [];
var connectCounter=0;
var svr = net.createServer()
svr.on("connection",function(sock) {
connectCounter++;
var remoteAddress = sock.remoteAddress + ":" + sock.remotePort;
console.log("new client connection is made %s", remoteAddress);
sockets.push(sock);
sock.write('Welcome to the server!\n');
sock.on('data', function(data) {
console.log("Data from %s :%s", remoteAddress, data);
sock.write("Hello", + data);
console.log("connection_id:", + sock.id);
console.log("Number of active state(connection) :",connectCounter);
});
sock.on('end', function() {
connectCounter--;
console.log('Disconnected: ' + sock.remoteAddress + ':' + sock.remotePort);
console.log("Number of active state(disconnected) :",connectCounter);
var idx = sockets.indexOf(sock);
if (idx != -1) {
delete sockets[idx];
}
});
});
var svraddr = 'localhost';
var svrport = 3000;
svr.listen(svrport, svraddr);
console.log('Server Created at ' + svraddr + ':' + svrport + '\n');
My android code
socket = new Client("localhost", 3000);
socket.setClientCallback(new Client.ClientCallback() {
#Override
public void onMessage(String message) {
System.out.println("Socket_connection_msg" + message);
}
#Override
public void onConnect(Socket sockett) {
try {
JSONObject jsonObject=new JSONObject();
jsonObject.put("name" ,"MainActivity");
jsonObject.put("value" ,"45");
socket.send(jsonObject.toString());
} catch (JSONException e) {
e.printStackTrace();
}
System.out.println("Socket_connection" + sockett.isConnected());
//socket.disconnect();
}
#Override
public void onDisconnect(Socket socket, String message) {
System.out.println("Socket_connection_disconnect" + socket.isConnected()+ message);
}
#Override
public void onConnectError(Socket socket, String message) {
System.out.println("Socket_connection_error" + message);
}
});
socket.connect();
My console output is
When a new android device is connected active state increases and if user goes out of app it disconnects and connection gets decremented by 1.
Now i need the response to displayed in HTML page
I am new to nodejs , any help would be appreciated
Thank you in advance.
I want to connect SignalR android client with server. I have search too much but cant get solution of my problem i am new to signalR so please anyone tell me the solution. I am getting following exception
java.util.concurrent.ExecutionException: microsoft.aspnet.signalr.client.transport.NegotiationException: There was a problem in the negotiation with the server
Here is my code
Server Side
aspx file
var IWannaChat = $.connection.myChatHub;
$.connection.hub.start().done(function () {
console.log("id : %o", $.connection.hub.id);
document.getElementById("connectionid").innerHTML =
"Name: " + $('#displayname').val() +
"<br/> Connection ID: " + $.connection.hub.id;
}
.cs file
[HubName("myChatHub")]
public class LetsChat : Hub
{
public override Task OnConnected()
{
System.Diagnostics.Debug.WriteLine("Connected");
return base.OnConnected();
}
public override Task OnDisconnected()
{
System.Diagnostics.Debug.WriteLine("Disconnected");
return base.OnDisconnected();
}
Android code
Platform.loadPlatformComponent(new AndroidPlatformComponent());
String serverUrl = "http://192.168.100.72/Chat.aspx";
mHubConnection = new HubConnection(serverUrl);
String SERVER_HUB_CHAT = "myChatHub";
mHubProxy = mHubConnection.createHubProxy(SERVER_HUB_CHAT);
ClientTransport clientTransport = new ServerSentEventsTransport(mHubConnection.getLogger());
SignalRFuture<Void> signalRFuture = mHubConnection.start(clientTransport);
try {
signalRFuture.get();
} catch (InterruptedException | ExecutionException e) {
Log.e("SimpleSignalR Exception", e.toString());
return;
}
mHubConnection.connected(new Runnable() {
#Override
public void run() {
Global.displayLog("SignalR_connection Connected connection_Id " + mHubConnection.getConnectionId() + " ConnectionToken" +
mHubConnection.getConnectionToken());
// Toast.makeText(SignalRService.this,"Connected",Toast.LENGTH_SHORT).show();
}
});
Please help me what i am doing wrong on both sides
I am using "randdusing/cordova-plugin-bluetoothle" plugin in PhoneGap/Cordova App to create a Bluetooth application. I am using a simple example which is given on GitHub page of the plugin. but I am not getting any device listed but getting a message Scanning for devices (will continue to scan until you select a device)...
Below is the Code I am using
document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady() {
bluetoothle.initialize({
request: true,
statusReceiver: false
}, initializeSuccess, handleError);
}
function initializeSuccess(result) {
if (result.status === "enabled") {
log("Bluetooth is enabled.");
log(result);
} else {
document.getElementById("start-scan").disabled = true;
log("Bluetooth is not enabled:", "status");
log(result, "status");
}
}
function handleError(error) {
var msg;
if (error.error && error.message) {
var errorItems = [];
if (error.service) {
errorItems.push("service: " + (uuids[error.service] || error.service));
}
if (error.characteristic) {
errorItems.push("characteristic: " + (uuids[error.characteristic] || error.characteristic));
}
msg = "Error on " + error.error + ": " + error.message + (errorItems.length && (" (" + errorItems.join(", ") + ")"));
} else {
msg = error;
}
log(msg, "error");
if (error.error === "read" && error.service && error.characteristic) {
reportValue(error.service, error.characteristic, "Error: " + error.message);
}
}
var foundDevices = [];
function startScan() {
log("Starting scan for devices...", "status");
document.getElementById("devices").innerHTML = "";
document.getElementById("services").innerHTML = "";
document.getElementById("output").innerHTML = "";
if (window.cordova.platformId === "windows") {
bluetoothle.retrieveConnected(retrieveConnectedSuccess, handleError, {});
} else {
bluetoothle.startScan(startScanSuccess, handleError, {
services: []
});
}
}
function startScanSuccess(result) {
log("startScanSuccess(" + result.status + ")");
if (result.status === "scanStarted") {
log("Scanning for devices (will continue to scan until you select a device)...", "status");
} else if (result.status === "scanResult") {
if (!foundDevices.some(function (device) {
return device.address === result.address;
})) {
log('FOUND DEVICE:');
log(result);
foundDevices.push(result);
addDevice(result.name, result.address);
}
}
}
function retrieveConnectedSuccess(result) {
log("retrieveConnectedSuccess()");
log(result);
result.forEach(function (device) {
addDevice(device.name, device.address);
});
}
function addDevice(name, address) {
var button = document.createElement("button");
button.style.width = "100%";
button.style.padding = "10px";
button.style.fontSize = "16px";
button.textContent = name + ": " + address;
button.addEventListener("click", function () {
document.getElementById("services").innerHTML = "";
connect(address);
});
document.getElementById("devices").appendChild(button);
}
function log(msg, level) {
level = level || "log";
if (typeof msg === "object") {
msg = JSON.stringify(msg, null, " ");
}
console.log(msg);
if (level === "status" || level === "error") {
var msgDiv = document.createElement("div");
msgDiv.textContent = msg;
if (level === "error") {
msgDiv.style.color = "red";
}
msgDiv.style.padding = "5px 0";
msgDiv.style.borderBottom = "rgb(192,192,192) solid 1px";
document.getElementById("output").appendChild(msgDiv);
}
}
This is my first Bluetooth LE Project in Cordova. Please help me and suggest any other plugin better than this with good documentation.
Thanks.
If you are testing your app on Android 6+ you need to request permission first in order to use the Bluetooth functionality of the device. Otherwise your app will silently fail and you won't see any devices discovered. You can use the built-in method of the Bluetooth LE plugin for this
bluetoothle.requestPermission().then(success, fail)
Or you can add cordova-plugin-android-permissions, should you need to request other permissions as well.