What I have:
A simple node server listening on port 8100 for POST requests:
var express = require('express');
var bodyParser = require('body-parser');
var port = 8100;
var app = express();
app.use(bodyParser.json());
app.post('/v1/auth/jwt/login', (req, res) => {
console.log('Here is the body:');
console.log(req.body);
res.json({ message: 'received' });
});
app.listen(port, () => console.log(`Example app listening on port ${port}!`));
I can confirm that this logs and return a response correctly. (via PostMan/Insomnia/etc)
What I'm trying to do is hit this with a Vert.x webclient:
public void getServiceJwt() {
String loginJwt = getLoginJwt();
System.out.println("Initiating request");
JsonObject payload = new JsonObject()
.put("role", "some-service")
.put("jwt", loginJwt);
client
.post("/v1/auth/jwt/login")
.sendJsonObject(payload, ar -> {
if (ar.succeeded()) {
System.out.println("things went well");
} else {
System.out.println(ar);
System.out.println("something went horribly wrong");
}
});
}
The request happens, as I can see the payload data logged. What seems to not happen is the ar callback. I don't get a log in either case. It's almost as if the request is not returning... but I have no idea how to check. There is no stack trace, no errors. Just, nothing. This example is pretty much right out of the docs.
I'm at a loss on how to troubleshoot this further.
Related
I am trying to connect my android app to NodeJS server.
ANDROID PART
First I include the Socket.io library to my dependency
implementation('io.socket:socket.io-client:2.0.0') {
exclude group: 'org.json', module: 'json'
}
My JAVA code
//all variables used are initialized, defined and working perfectly
try {
socket = IO.socket(socketUrl);
socket.on(Socket.EVENT_CONNECT, args -> runOnUiThread(() -> socket.emit("connected", true)));
socket.connect();
} catch (URISyntaxException e) {
e.printStackTrace();
}
SERVER SIDE
var express = require('express'),
app = express(),
socket = require('socket.io'),
router = express.Router();
router.get('/', function(req, res, next) {
res.render('index', { title: 'Express' });
});
var server = app.listen(4000, function(){
console.log('listening for requests on port 4000,');
});
let io = socket(server);
io.on('connection', function(socket){
console.log(`${socket.id} is connected`);
});
module.exports = router;
Now the problem is after starting the Server, and I try to connect my android app to it, I keep getting an error from Socket.io connection, like the image below
I have searched SO for solution and I get multiple answers relating to this, but I still keep getting the same error
My Socket.io version is 8.5.5
you can not use socket directly via express, here is the documentation.
try this code instead.
var express = require('express'),
app = express()
const httpServer = require("http").createServer(app);
const io = require("socket.io")(httpServer);
router = express.Router();
router.get('/', function(req, res, next) {
res.render('index', { title: 'Express' });
});
io.on('connection', function(socket){
console.log(`${socket.id} is connected`);
});
httpServer.listen(4000, function(){
console.log('listening for requests on port 4000,');
});
module.exports = router;
I am trying to use a Java Socket Server with socket.io-client, but it has an erratic behavior from the moment of the connection. It manages to stablish connection, but then this exception is thrown in Angular:
GET https://127.0.0.1:1532/socket.io/?EIO=4&transport=polling&t=N__rEfS net::ERR_SSL_PROTOCOL_ERROR
And the Server in Java only receives scrambled text repatedly
and the Client starts connecting and disconnecting over and over again. Why is this happening? Is there any way to get a cleaner Socket connection from Angular 13 to Java?
I use this Java Socket Server for many other applications and it works perfectly for everything else but this.
This is the routine that reads the Java Server:
void handleClientRequest() {
try{
mBufferIn = new BufferedReader(new InputStreamReader( socket.getInputStream()));
mBufferOut = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);
//in this while the client listens for the messages sent by the server
while (clientRun) {
String clientMessage = mBufferIn.readLine();
if (clientMessage != null && mMessageListener != null) {
mMessageListener.messageReceived(clientMessage);
}
}
} catch(Exception e){
System.out.printf("%s: Unexpected client disconnection. Reason:%n", accountId);
e.printStackTrace();
}
}
And this is the Angular code:
this.socket = io('https://127.0.0.1:1532');
this.socket.on('connect', () => {
const engine = this.socket.io.engine;
console.log(engine.transport.name); // in most cases, prints "polling"
engine.once('upgrade', () => {
// called when the transport is upgraded (i.e. from HTTP long-polling to WebSocket)
console.log(engine.transport.name); // in most cases, prints "websocket"
});
engine.on('packet', ({ }) => {
// called for each packet received
});
engine.on('packetCreate', ({ }) => {
// called for each packet sent
});
engine.on('drain', () => {
// called when the write buffer is drained
});
engine.on('close', (reason: any) => {
// called when the underlying connection is closed
});
});
Code taken from https://socket.io/docs/v4/client-socket-instance/
Socket IO is a communication protocol implemented on the top of websocket
from my understanding (correct me if im wrong) you are using raw socket in java.
So very likely that "scrambled" text that you are receiving, is part of https handshake.
My suggestion as way forward, will be to use library that handles websocket connections.
I am trying to connect to a message queue running on a docker container using Reactor Netty. I am doing this as standalone, not using SpringFlux because of dependency issues.
From the examples in the Reactor Netty documentation I saw there is a way to connect to the Server and get a response:
public static void main(String[] args) {
String response =
HttpClient.create()
.headers(h -> h.add("my header", my_header)
.get()
.uri(my_uri)
.responseContent()
.aggregate()
.asString()
.block();
}
but when I try afterwards to display the output via System.out.println() nothing happens.
I also tried to understand how to use:
Flux<V> response(BiFunction<HttpClientResponse,ByteBufFlux,Publisher<V>> receiver)
But I am not sure exactly what to do.
I saw in the documentation there is a class called Connection, which uses a TCPClient and has a method subscribe.
I am kind of lost, can you possibly point me in the right direction of implementing this in Reactor Netty without the use of spring-flux?
Thank you
EDIT:
After some experimentation i got this:
private Disposable subscribe() {
return HttpClient.create()
.headers(h -> h.add("my header", my_header)
.get()
.uri(my_uri)
.response((res, bytes) - > {
System.out.println(bytes.asString());
return bytes.asString();})
.subscribe();
}
This gives me a FluxHandle, how can I use that to actually read the body of the response?
So I figured out how to subscibe and read the data recieved from the Server and even transform the data to JSON, using the jackson library, to be more easily read by my code.
private Disposable subscribe() {
return HttpClient.create()
.headers(h -> h.add("my header", my_header)
.get()
.uri(my_uri)
.response((resp, bytes) -> {
return bytes.asString();
})
.subscribe(response -> {
try {
consumeData(new ObjectMapper()
.readValue(response, MyData.class));
} catch (IOException ex) {
System.out.println("ERROR converting to json: " + ex);
}
});
}
it seems that when using the subscribe() method i can listen to incoming responses and do something with them. I still need to add a way for the connection to close when the server stops, or the message queue is shut down, so the client doesn't hang on non-existent message queue.
I'm trying to connect my android app to a nodeJS server using Socket.io
this is the connection code from android:
final String URL = "http://192.168.0.103:3000";
try {
mSocket = IO.socket(URL);
mSocket.connect();
mSocket.emit("message", "Hello");
Toast.makeText(MainActivity.this, "Socket Connected!!",Toast.LENGTH_SHORT).show();
} catch (URISyntaxException e) {
e.printStackTrace();
}
nothing more on android, also I have my internet permission added to manifest and I'm using next library:
implementation 'com.github.nkzawa:socket.io-client:0.6.0'
On the server-side, I'm using also Socket.io library, but for nodeJS and the connection is made like in following lines of code:
const app = express();
app.set("port", process.env.PORT || 3000);
let http = require("http").Server(app);
let io = require("socket.io")(http);
app.use(bodyParser.json());
app.use(function(req, res, next) {
res.header("Content-Type", "application/json");
next();
});
app.get("/", (req: any, res: any) => {
res.send("hello world");
});
io.on("connection", function(socket: any) {
console.log("a user connected");
// whenever we receive a 'message' we log it out
socket.on("message", function(message: any) {
console.log(message);
});
});
const server = http.listen(3000, function() {
console.log("listening on *:3000");
});
When I'm trying to connect from android any line of code is executed with success, even the Toast message, but on server nothing. Also, I made a little script on nodeJS using "socket.io-client" library, for testing where I'm trying to connect to the same server and all the stuff is working fine, the connection is created with success, I receive the message on the terminal from the server, and from the script also I have a success message. the following script looks like this:
var io = require("socket.io-client");
function checkSocketIoConnect(url, timeout) {
return new Promise(function (resolve, reject) {
var errAlready = false;
timeout = timeout || 5000;
var socket = io(url, { reconnection: false, timeout: timeout });
// success
socket.on("connect", function () {
clearTimeout(timer);
resolve();
socket.close();
});
// set our own timeout in case the socket ends some other way than what we are listening for
var timer = setTimeout(function () {
timer = null;
error("local timeout");
}, timeout);
// common error handler
function error(data) {
if (timer) {
clearTimeout(timer);
timer = null;
}
if (!errAlready) {
errAlready = true;
reject(data);
socket.disconnect();
}
}
// errors
socket.on("connect_error", error);
socket.on("connect_timeout", error);
socket.on("error", error);
socket.on("disconnect", error);
});
}
checkSocketIoConnect("http://192.168.0.103:3000").then(function () {
// succeeded here
console.log("working");
}, function (reason) {
// failed here
console.log("why not: ", reason);
});
Changed:
How to response http request from socket.
Web code:
public void start() {
Router router = Router.router(vertx);
router.route("/api/getdata").handler(this::getData);
vertx.createHttpServer().requestHandler(router::accept).listen(8080);
}
private void getData(RoutingContext routingContext) {
vertx.eventBus().send(ServerVerticle.ADDRESS, pricemessage, reply -> {
});
}
Socket code:
public void start() {
final EventBus eb = vertx.eventBus();
NetClient netClient = vertx.createNetClient();
if (ar.succeeded()) {
socket.handler(this::onDataReceived);
eb.consumer(ServerVerticle.ADDRESS, message -> {
socket.write(buffer); // request from the getData method
message.reply(data);// no data here, it's in the handler
}
}
}
private void onDataReceived(Buffer buffer) {
// buffer changed to JsonObject here
vertx.eventBus().send("some address here", jsonObject);
}
The socket handler has no return value. Just a eventbus send.
And I don't know how to response this jsonObject to the http request.
========================================================================
Old question, maybe not clear.
I have a vertex that handles the socket write and response.
public void start() { // 1
NetClient netClient = vertx.createNetClient();
netClient.connect(port, host, ar -> {
socket = ar.result(); // NetSocket
socket.handler(this::doSocketHandleMethod);
socket.write(BYTEBUFFER);// buffer here
})
}
private void doSocketHandleMethod(Buffer buffer){ // socket handler
// process data here and send
vertx.eventBus().send(ADDRESS, data here);
}
I use the below code to fetch the response from the http request.
public void start() {
Router router = Router.router(vertx);
router.route(API_GET).handler(this::getData);
vertx.eventBus().consumer(ADDRESSHERE, msg -> {
// get data from the socket send. 2
});
vertx.createHttpServer().requestHandler(router::accept).listen(8080, result -> {
});
}
private void getData(RoutingContext routingContext) {
vertx.eventBus().send(ADDRESS, message); // send message to the top // 1 verticle
// 3
}
The question is that the second code mention above gets the the data, but not sure how to fetch the response from the http reqest 3.
The (HttpServerRequest) is passed to the route (requestHandler(router::accept)) and is contained in the RoutingContext. "As HTTP requests are received by the server, instances of [...].HttpServerRequest will be created and passed to this handler." - JavaDoc
So, if the data arrives at 2 and you want to do a response to a HttpServerRequest (as a third step), you can use routingContext.response() in the getData() method, to get a HttpServerResponse.
If you want to handle a http server request, by sending a message to a consumer that is getting some data from a socket and want to send this result as a reply to the specific http server request, then you may do something like this:
// Send a message and get the response via handler
private void getData(RoutingContext routingContext) {
vertx.eventBus().send(ADDRESS, message, handler -> {
if(handler.succeded()) {
routingContext.response().end(handler.result());
}
else {
// error
}
});
}
// To reply to a message do
vertx.eventBus().consumer(ADDRESSHERE, msg -> {
// get data from the socket send. 2
msg.reply(data); // you can only do a reply once. Put data into reply
});
As far as I know, the event bus only knows "send and reply" and not a concept like a socket. It looks like you want to send data everytime new data is available through the socket.
You can write something to a httpResponse mutliple times, so you need to save a reference to the response object.
But I do not know, if that is such a good idea. I would recommend to encapsulate the socket-get-data process. The "socket" verticle only answers once, with the whole buffer it got. Here are two examples on what I mean.
// open socket
vertx.eventBus().consumer("ADRRESS", message -> {
// execute this on worker thread to not block the event bus thread
vertx.executeBlocking(future -> {
Buffer buffer = Buffer.buffer();
socket.handler(buff -> buffer.appendBuffer(buff)) // read data
.endHandler(endHandler -> {
// no more data to read
socket.pause();
future.complete(buffer);
})
.resume() // socket was paused, now read the data
.exceptionHandler(err -> future.fail(err)); // handle exception
}, result -> {
if(result.succeeded()) {
message.reply(result.result()); // reply with the buffer content
}
else {
message.reply(result.cause()); // may want to send error later
}
});
});
// connect and get a new socket every time
vertx.eventBus().consumer("ADRRESS", message -> {
// execute this on worker thread to not block the event bus thread
vertx.executeBlocking(future -> {
netClient.connect(1, "", netSocketHandler -> {
if(netSocketHandler.succeeded()) {
Buffer buffer = Buffer.buffer();
netSocketHandler.result().handler(buff -> buffer.appendBuffer(buff)) // read data
.endHandler(endHandler -> {
// no more data to read
future.complete(buffer);
netSocketHandler.result().close(); // close the NetSocket once finished
})
.exceptionHandler(err -> {
netSocketHandler.result().close();
future.fail(err);
}); // handle exceptions
}
else {
future.fail(netSocketHandler.cause());
}
});
}, result -> {
if(result.succeeded()) {
message.reply(result.result()); // reply with the buffer content
}
else {
message.reply(result.cause()); // may want to send error later
}
});
});
If this realy does not help you, I'm sorry, and maybe this is not the concept you are looking for.