I have two methods in my SignalRService class on client side:
public startConnection(): void {
this.connection.start().done((data: any) => {
console.log('Now connected ' + data.transport.name + ', connection
ID= ' + data.id);
//this.connectionEstablished.emit(true);
this.connectionExists = true;
}).fail((error: any) => {
console.log('Could not connect ' + error);
//this.connectionEstablished.emit(false);
});
}
public stopConnection():void {
this.connection.stop();
console.log('Stop connection');
}
Initialization goes in constructor like this:
this.connection = $.hubConnection(environment.apiUrl);
this.connection.qs = "Bearer="+this._authService.getToken();
// create new proxy as name already given in top
this.proxy = this.connection.createHubProxy(this.proxyName);
I need to call start again after stop but it fails with exception:
ERROR Error: SignalR: Connection has not been fully initialized. Use
.start().done() or .start().fail() to run logic after the connection has
started.
Help me please with it!
Related
I can't figure out when and where exactly the "greetings" room is created in the code.
This is my js code
function connect() {
var socket = new SockJS('/gs-guide-websocket');
stompClient = Stomp.over(socket);
stompClient.connect({}, function (frame) {
setConnected(true);
console.log('Connected: ' + frame);
stompClient.subscribe('/topic/greetings', function (greeting) {//here it subsribe to this chat channel
showGreeting(JSON.parse(greeting.body).content);
});
});
}
and this is java
#Controller
public class GreetingController {
#MessageMapping("/hello")
#SendTo("/topic/greetings")
public Greeting greeting(HelloMessage message) throws Exception {
return new Greeting("Hello, " + HtmlUtils.htmlEscape(message.getName()) + "!");
}
}
In js I see that message will be send to "/topic/greetings", and in java code I see where will be server send answer(/topic/greetings), but where in code this topic have been created ?
I'm trying to build a TCP server on node JS. The idea is to have multiple TCP clients connect and send / receive data(from server to client / client to server) and to have some sort of authentication (at least to enter a strong password) Also not sure if this approach is worth it. But, I've come up with something (most from online sources and docs) and crated below code.
Code runs and I can connect, but if I send data from client to server, the "password" check function fires up and each time I enter the correct password, a new (duplicate connection) is created. Seems like it keeps calling the same function on each input.
Desired behavior would be ; once client try's to connect, needs to provide the password and then start sending date. Also could someone give me a hint on how to send data back from server, or is it even possible. Or do I need to create a separate function for server.createConnection()
thanks in advance
UPDATE :I've changed the code a bit, but the main issue remains. this bit was supposed to check whether "clientAddress" exists and if so skip the auth part all together.
server.on('connection', (socket) => {
let clientAddress = `${socket.remoteAddress}:${socket.remotePort}`;
console.log(clientAddress)
if(sock.indexOf(clientAddress) !== -1){
console.log('devie found, opening communication')
newConnectionHandler(socket,clientAddress)
} else {
console.log('devie not found, need to authenticate')
userAuth(socket,clientAddress)
}
but as you can guess, it's not working :) if I manually specify the "clientAddress" it works , if I place "sock.push(clientAddress);" within the first block of code, it also works. No auth is asked. But when it's placed within
function userAuth(socket,clientAddress){
socket.write('password : ' )
socket.on('data', function (data) {
let pass = data.toString()
if (pass == password) {
sock.push(clientAddress);
console.log(sock)
newConnectionHandler(socket,clientAddress)
return;
} else {
//console.log(pass)
socket.write('Sorry, you cannot access the server \n')
console.log('acess denied for ' + socket.remoteAddress + ':' + socket.remotePort + '\n')
socket.write('connection closed')
socket.destroy()
}
})
}
code does run as expected and goes all the way till
function newConnectionHandler(socket,clientAddress){
//console.log(sock)
socket.write('Welcome \n')
socket.on('data', function(data1){
console.log("Client Sent: " + data1);
});
but as soon as I send a new message from the client, it goes back as if it was never authenticated and treats my input as the password and because it does not match with the actual password,it destroys the connection.
can someone please give me a hand...
const net = require('net');
const port = 3001;
const host = '192.168.0.165';
const server = net.createServer()
let sock = [];
let password = 123
//server.on('listening',createConnection);
server.on('connection', (socket) => {
let clientAddress = `${socket.remoteAddress}:${socket.remotePort}`;
console.log(clientAddress)
if(sock.indexOf(clientAddress) !== -1){
console.log('devie found, opening communication')
newConnectionHandler(socket,clientAddress)
} else {
console.log('devie not found, need to authenticate')
userAuth(socket,clientAddress)
}
server.on('error', errorHandler);
function errorHandler(err){
console.log(`Error occurred in ${clientAddress}: ${err.message}`);
}
function userAuth(socket,clientAddress){
socket.write('password : ' )
socket.on('data', function (data) {
let pass = data.toString()
if (pass == password) {
sock.push(clientAddress);
console.log(sock)
newConnectionHandler(socket,clientAddress)
return;
} else {
//console.log(pass)
socket.write('Sorry, you cannot access the server \n')
console.log('acess denied for ' + socket.remoteAddress + ':' + socket.remotePort + '\n')
socket.write('connection closed')
socket.destroy()
}
})
}
function newConnectionHandler(socket,clientAddress){
//console.log(sock)
socket.write('Welcome \n')
socket.on('data', function(data1){
console.log("Client Sent: " + data1);
});
socket.once('close', (data) => {
let index = sock.findIndex((o) => {
return o.remoteAddress === socket.remoteAddress && o.remotePort === socket.remotePort;
})
if (index !== -1) sock.splice(index, 1);
sock.forEach((sock) => {
socket.write(`${clientAddress} disconnected\n`);
});
console.log(`connection closed: ${clientAddress}`);
});
}
/* function createConnection(){
// Start a connection to the server
var socket = server.on('connect',function(){
// Send the initial message once connected
socket.write({question: "Hello, world?"});
});
// Whenever the server sends us an object...
socket.on('data', function(data){
// Output the answer property of the server's message to the console
console.log("Server's answer: " + data.answer);
});
} */
})
server.listen(port, host, () => {
console.log('TCP Server is running on port ' + port + '.');
});
so it appears as the only bit of code that was causing the authentication loop was the
function userAuth(socket,clientAddress){
socket.write('password : ' )
**socket.on('data', function (data) {**
let pass = data.toString()
after changing "on" with "once" it is now functioning properly. I tested with two TCP clients, both connected and was asked to enter a password. They can both actively send messages to the server and both disconnected properly in the end.
this is the code if anyone finds any use for it :) the connection it's self is still unencrypted so not good for sending/receiving sensitive data.
const net = require('net');
const port = 3001;
const host = '192.168.0.165';
const server = net.createServer()
let sock = [];
let password = 123
//server.on('listening',createConnection);
server.on('connection', (socket) => {
let clientAddress = `${socket.remoteAddress}:${socket.remotePort}`;
console.log(clientAddress)
if(sock.indexOf(clientAddress) !== -1){
console.log('devie found, opening communication')
newConnectionHandler(socket,clientAddress)
} else {
console.log('devie not found, need to authenticate')
userAuth(socket,clientAddress)
}
})
server.on('error', errorHandler);
function errorHandler(err){
console.log(`Error occurred in ${clientAddress}: ${err.message}`);
}
function userAuth(socket,clientAddress){
socket.write('password : ' )
socket.once('data', function (data) {
let pass = data.toString()
if (pass == password) {
sock.push(clientAddress);
console.log(sock)
newConnectionHandler(socket,clientAddress)
return;
} else {
//console.log(pass)
socket.write('Sorry, you cannot access the server \n')
console.log('acess denied for ' + socket.remoteAddress + ':' + socket.remotePort + '\n')
socket.write('connection closed')
socket.destroy()
}
})
}
function newConnectionHandler(socket,clientAddress){
//console.log(sock)
socket.write('Welcome \n')
socket.on('data', function(data1){
console.log("Client Sent: " + data1);
});
socket.on('close', function(data) {
let index = sock.findIndex(function(o) {
return o.remoteAddress === sock.remoteAddress && o.remotePort === sock.remotePort;
})
if (index !== -1) sock.splice(index, 1);
console.log('CLOSED: ' + socket.remoteAddress + ' ' + socket.remotePort);
});
}
/* function createConnection(){
// Start a connection to the server
var socket = server.on('connect',function(){
// Send the initial message once connected
socket.write({question: "Hello, world?"});
});
// Whenever the server sends us an object...
socket.on('data', function(data){
// Output the answer property of the server's message to the console
console.log("Server's answer: " + data.answer);
});
} */
server.listen(port, host, () => {
console.log('TCP Server is running on port ' + port + '.');
});
In the event handler window.onunload the client fires event:
function onPageUnload() {
userSocket.emit('command', "{'cloudBackup': 'cancel'}");
}
On the server I have a listener:
io.on('connect', function(socket) {
console.log("RIKO ::: SocketIO connected!");
socket.on('command', function(msg) {
console.log("RIKOO ::: command with msg : " + msg);
backupOnceProcCanceled = true;
console.log("PC = " + backupOnceProcCanceled)
// throw new Error("RIKO ::: Thrown Error at backup2.js line 106")
});
socket.on( 'disconnect', function(reason) {
console.log("RIKO ::: SocketIO disconnected! Reason : " + reason );
})
})
When the client refresh/leave/navigate the page I see that the browser fires the event
('command', "{'cloudBackup': 'cancel'}")
But the server doesn't detect the event. Only when the port is closed:
RIKO ::: SocketIO disconnected! Reason : transport close
The wildcard you are using isn't a valid way of catching all events. You can write a little middleware to catch those:
io.on('connect', function(socket) {
console.log("RIKO ::: SocketIO connected!");
socket.use((packet, next) => {
console.log("RIKOO ::: command with msg : " + msg);
backupOnceProcCanceled = true;
console.log("PC = " + backupOnceProcCanceled)
// throw new Error("RIKO ::: Thrown Error at backup2.js line 106")
next();
});
socket.on( 'disconnect', function(reason) {
console.log("RIKO ::: SocketIO disconnected! Reason : " + reason );
})
})
The socket.use() function has been added for this purpose specifically. You can take a look at the documentation at the following link: https://socket.io/docs/server-api/#socket-use-fn
Or alternatively you can catch this particular event by just changing the * to command.
Very strange but inserting delay in "onPageUnload" function solved the problem.
function waitMs(ms) {
var start = Date.now()
var now = start;
while(now - start < ms){
now = Date.now()
}
}
function onPageUnload() { //window.onunload = onPageUnload;
userSocket.emit('command', "{'cloudBackup': 'cancel'}");
waitMs(50);
console.log("SOCKET send cloudBackup cancel 1 ");
}
I am saying strange because the event should be handled despite the delay.
May be when the page is being reloaded the Server load is high and before it can handle the event the port is already closed.
Still not sure.
Im trying to make a simple application. That is When I write a word at edittext in android app such as "Hi", Then android app send message "Hi" to node.js server and node.js server send message "Hi has sent successflly" to android app. This is just a example, actually my object is android send a data(message) to server, and receive another data(message) from server.
The problem is this. When I write a word at android app and press button, the message transmitted successfully(I can confirm by console at node.js). But I cant send message to android from node.js .. When I press send button, My android app shut down..
What android says is "java.lang.NullPointerException: Attempt to invoke virtual method 'void android.app.Activity.runOnUiThread(java.lang.Runnable)' on a null object reference" ..
Yesterday, this error didn't happened and another error occured. "cannot cast string to JSONObject."
I will show you my code.
Server Side(Node.js)
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
var port = 12000;
app.get('/', function(req, res) {
res.sendFile('index.html');
})
io.on('connection', function(socket) {
console.log('Android device has been connected');
socket.on('message', function(data) {
console.log('message from Android : ' + data);
Object.keys(io.sockets.sockets);
Object.keys(io.sockets.sockets).forEach(function (id) {
console.log("ID : ", id );
io.to(id).emit('message', data);
console.log(data + ' has sent successfully');
})
/*if (data != null) {
io.emit('message', {message : data + ' has received successfully'});
}*/
})
socket.on('disconnect', function() {
console.log('Android device has been disconnected');
})
})
http.listen(port, function() {
console.log('Server Start at port number ' + port);
})
Client Side (Android)
private Emitter.Listener handleIncomingMessages = new Emitter.Listener(){
#Override
public void call(final Object... args){
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
JSONObject data = (JSONObject) args[0];
String message;
try {
message = data.getString("text").toString();
Log.i("result", message);
addMessage(message);
} catch (JSONException e) {
Log.e("result", "Error : JSONException");
return;
} catch (ClassCastException e) {
Log.e("result", "Error : ClassCastException");
e.printStackTrace();
return;
}
}
});
}
};
private void sendMessage(){
String message = mInputMessageView.getText().toString().trim();
mInputMessageView.setText("");
addMessage(message);
JSONObject sendText = new JSONObject();
try{
sendText.put("text", message);
socket.emit("message", message);
}catch(JSONException e){
}
}
private void addMessage(String message) {
mMessages.add(new Message.Builder(Message.TYPE_MESSAGE)
.message(message).build());
// mAdapter = new MessageAdapter(mMessages);
mAdapter = new MessageAdapter( mMessages);
mAdapter.notifyItemInserted(0);
scrollToBottom();
}
private void scrollToBottom() {
mMessagesView.scrollToPosition(mAdapter.getItemCount() - 1);
}
I already searched similar problems that other people asked, but It didn't give me solution. Please help me. Thank you for reading long question.
p.s Because Im not English speaker, Im not good at English .. There will be many problems at grammar and writing skills. Thanks for understanding...
Reason this happens is because method getActivity() returns null. This might happen if you run this on a fragment after it is detached from an activity or activity is no longer visible. I would do a normal null check before like:
Activity activity = getActivity();
if(activity != null) {
activity.runOnUiThread(new Runnable() {...}
}
I'm not familiar with socket.emit() method but it might throw network exception since it's running on UI thread and you are not allowed to do that. I recommend using RxJava/RxAndroid if you want to do this on another thread.
If you want to do network operation just use it like this:
Observable
.fromRunnable(new Runnable {
void run() {
// here do your work
}
})
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<Void>() {
#Override
public void onCompleted() {
// not really needed here
}
#Override
public void onError(Throwable e) {
// handle errors on UI thread
}
#Override
public void onNext(Void void) {
// do something on UI thread after run is done
}
});
Basically what it does it calls method call from Callable you just made on separate thread and when it's over it invokes onNext method if no exception was thrown or onError method if exception was thrown from Subscriber class.
Note that Response class isn't part of the RxJava/RxAndroid API and you can make it if you want. You can make it a simple POJO class or anything else you need it to be. If you don't need to have response you can use Runnable instead of Callable and it will work just fine.
In order for this to work you need to add this dependencies to your modules Gradle file:
dependencies {
compile 'io.reactivex:rxandroid:1.2.1'
compile 'io.reactivex:rxjava:1.1.6'
}
i just completed a web based chat application based on ajax/php. But the problem with this app is that it has to continuously poll server to check for new messages, which in turn overloads the server if many people are using this app simultaneously.
now i want to implement a socket based chat app in JavaScript. I know there is no support for sockets in JavaScript so i decided to use "Flash as a socket gateway for JavaScript" i am using Linux and and new to flash. can someone help me with how to achieve this.
basically,
1) I want to make a small SWF object that just handles socket logic(minimum width and height so i can hide it easily with -ve margin.
2) I want to access this swf object with JavaScript
i got a code for simple socket in actionscript (from internet) but i cannot get it to compile using mxmlc(free flash compiler).
heres the code...
myXML = new XMLSocket;
myXML.onConnect = handleConnect;
myXML.onXML = handleXML;
myXML.onClose = handleDisconnect;
myXML.connect("http://www.yourServer.com", 12345);
function handleConnect(connectionStatus){
connectionStatus ? trace("Connected.") : trace("Connection failed.");
}
function handleXML(xmlObject){
trace("Object recieved:: "+xmlObject);
}
function sendXML(textToSend){
myXML.send(new XML('"+textToSend+""));
}
function handleDisconnect(){
trace("Connection lost.");
}
function closeConnection(){
trace("Closing connection to server.");
myXML.close();
}
i got a better code but this also does not compile
package
{
import flash.errors.*;
import flash.events.*;
import flash.net.Socket;
public class ChatSocket extends Socket
{
public var host:String;
public var port:uint;
private var socket:Socket;
public static var SOCK_CONNECTED:String = "onSockConnect";
public static var SOCK_IOERROR:String = "onSockIOError";
function ChatSocket(h:String, p:uint)
{
host = h;
port = p;
socket = this;
super(host, port);
initListeners();
}
public function sendMessage(str:String):void
{
if(connected)
{
socket.writeUTFBytes(str + "\n");
}
else
{
trace("Not connected, message not sent!");
}
}
public function readMessage():void
{
if(connected)
{
var str:String = socket.readUTFBytes(socket.bytesAvailable);
trace("Socket Server Response: " + str);
}
else
{
trace("No message read, not connected!");
}
}
private function initListeners():void
{
socket.addEventListener(Event.CLOSE, closeHandler);
socket.addEventListener(Event.CONNECT, connectHandler);
socket.addEventListener(IOErrorEvent.IO_ERROR,
ioErrorHandler);
}
private function closeHandler(event:Event):void
{
trace("Connection to [" + host + "] closed");
}
private function ioErrorHandler(event:IOErrorEvent):void
{
dispatchEvent(new Event(SOCK_IOERROR));
}
private function connectHandler(event:Event):void
{
trace("Connected to [" + host + "]");
dispatchEvent(new Event(SOCK_CONNECTED));
}
private function socketDataHandler(event:ProgressEvent):void
{
readMessage();
}
}
}
var sock:ChatSocket;
sock = new ChatSocket('127.0.0.1', 9990);
sock.addEventListener(ChatSocket.SOCK_CONNECTED, connected);
sock.addEventListener(ChatSocket.SOCK_IOERROR, ioError);
function ioError(e:Event):void
{
trace("Cant connect to " + sock.host + " on port " + sock.port);
}
function connected(e:Event):void
{
sock.sendMessage("are you hungry?");
}
ERROR IS:
localhost bin]$ ./mxmlc ChatSocket.as
Loading configuration file /home/lk/Documents/flex_sdk_3.4/frameworks/flex-config.xml
/home/lk/Documents/flex_sdk_3.4/bin/ChatSocket.as: Error: A file found in a source-path can not have more than one externally visible definition. ChatSocket;sock;ioError;connected
You may wish to check out gimite's web-socket-js. This is a socket gateway that conforms to the work-in-progress Web Socket API, so in future as browsers implement native WebSocket it will automatically switch over to the Flash-free alternative.
The following code lies outside the class and package {} blocks. That is not allowed.
var sock:ChatSocket;
sock = new ChatSocket('127.0.0.1', 9990);
sock.addEventListener(ChatSocket.SOCK_CONNECTED, connected);
sock.addEventListener(ChatSocket.SOCK_IOERROR, ioError);
function ioError(e:Event):void
{
trace("Cant connect to " + sock.host + " on port " + sock.port);
}
function connected(e:Event):void
{
sock.sendMessage("are you hungry?");
}
Declare a document class (that extends Sprite) and move ioError and connected methods to it. Make sock an instance variable instead of a local variable and add the declaration part of sock into its constructor.
//DocClass.as
package
{
public class DocClass
{
private var sock:ChatSocket;
public function DocClass()
{
sock = new ChatSocket('127.0.0.1', 9990);
sock.addEventListener(ChatSocket.SOCK_CONNECTED, connected);
sock.addEventListener(ChatSocket.SOCK_IOERROR, ioError);
}
private function ioError(e:Event):void
{
trace("Cant connect to " + sock.host + " on port " + sock.port);
}
private function connected(e:Event):void
{
sock.sendMessage("are you hungry?");
}
}
}