Event Emitter in Java

5.1k Views Asked by At

I am currently converting a NodeJS project to Java. At the moment I am detained in a problem that I have not found a solution. In my Node project, I have a function that works with EventEmitter(require('events')) and Net Sockets (require("net")), and uses the "emit" functions to send messages and "on" to receive. How can I do the same in Java ???

3

There are 3 best solutions below

1
On BEST ANSWER

Maybe you will need some like this:

Server side:

import java.io.*;

public class Conex {

final int PUERTO=5000;

ServerSocket sc;

Socket so;

DataOutputStream salida;

String mensajeRecibido;

//SERVIDOR

public void initServer()

{

BufferedReader entrada;

try

{

sc = new ServerSocket(PUERTO );/* crea socket servidor que escuchara en puerto 5000*/

so=new Socket();

System.out.println("Esperando una conexión:");

so = sc.accept();</pre>
<pre class="brush:java">//Inicia el socket, ahora esta esperando una conexión por parte del cliente

System.out.println("Un cliente se ha conectado.");

//Canales de entrada y salida de datos

entrada = new BufferedReader(new InputStreamReader(so.getInputStream()));

salida = new DataOutputStream(so.getOutputStream());

System.out.println("Confirmando conexion al cliente....");

salida.writeUTF("Conexión exitosa...n envia un mensaje :D");

//Recepcion de mensaje

mensajeRecibido = entrada.readLine();

System.out.println(mensajeRecibido);

salida.writeUTF("Se recibio tu mensaje.n Terminando conexion...");

salida.writeUTF("Gracias por conectarte, adios!");

System.out.println("Cerrando conexión...");

sc.close();//Aqui se cierra la conexión con el cliente

}catch(Exception e )

{

System.out.println("Error: "+e.getMessage());

}

}

}

Client side:

import java.io.*;

public class Conex {

final String HOST = "localhost";

final int PUERTO=5000;

Socket sc;

DataOutputStream mensaje;

DataInputStream entrada;

//Cliente

public void initClient() /*ejecuta este metodo para correr el cliente */

{

try

{

sc = new Socket( HOST , PUERTO ); /*conectar a un servidor en localhost con puerto 5000*/

//creamos el flujo de datos por el que se enviara un mensaje

mensaje = new DataOutputStream(sc.getOutputStream());

//enviamos el mensaje

mensaje.writeUTF("hola que tal!!");

//cerramos la conexión

sc.close();

}catch(Exception e )

{

System.out.println("Error: "+e.getMessage());

}

}

}
1
On

For receive messages with GET method:

import javax.ws.rs.Consumes; 
import javax.ws.rs.GET; 
import javax.ws.rs.Path; 
import javax.ws.rs.Produces; 
import javax.ws.rs.core.MediaType; 
import javax.ws.rs.core.Response; 

@Path("/helloworld") 
@Produces(MediaType.APPLICATION_JSON) 
@Consumes(MediaType.APPLICATION_JSON) 
public class HelloWorldRest {               

    @GET  
    public Response sayHello() {     
        return Response.ok("Hello World desde el API REST",MediaType.APPLICATION_JSON).build();   
    } 
}

For send messages with POST method:

@POST
public Response createUser(User userRequest) {
    userRequest.setId(users.size()+1l);
    this.users.add(userRequest);
    return Response.ok(userRequest).build();
}
0
On

This really depends on how this application is scaled. You have a few choices:

1. REST Instead of emit you can invoke a REST API to send the event. To receive you can have a service hosted that the other party would invoke once they are done with the event.

One thing to watch-out for in this approach is error-handling. What would you want to do if your event was not emitted because the REST API was down or if it timed out. If you cannot propagate this error to the client and have them retry... then you will need to implement a retry mechanism.

2. In-memory queue If this is a single-instance application where you just want to emit events move to the next task at hand while serving the request and there are no other instances that would interfere or be impacted by this work then you can choose to use an in-memory queue. You would need a listener for the same and a similar setup to receive your events. This is not really scalable if you want other instances that are free-to-serve to help out with one of the events. Also if for any reason this JVM dies in-flight the request will land in and error (same applies to #1 too)

3. JMS / kafka If this is a large application with separate processes helping with different tasks and these must be asynchronous then consider using a persistent queue or a stream like kafka.

All these approaches are feasible but you would need to look at your scenario and then apply one of these. Each of these come with a cost in-terms of resiliency / infra maintenance.