Filtering request duplicates - java

I wrote a simple Server:
Server.java:
package com.ltp.server.core;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import com.ltp.server.core.request.RequestProcessingTask;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
#NoArgsConstructor(access = AccessLevel.PRIVATE)
public class Server {
private static final ExecutorService CLIENTS_POOL = Executors.newFixedThreadPool(100);
private static final Logger LOGGER = LogManager.getLogger(Server.class);
public static void run(final int port) {
try (final ServerSocket serverSocket = new ServerSocket(port)) {
LOGGER.info(String.format("Server started listening on port %d", port));
while (true) {
try {
final Socket client = serverSocket.accept();
CLIENTS_POOL.submit(new RequestProcessingTask(client));
}catch (IOException e) {
LOGGER.error("Unable to read request data");
e.printStackTrace();
}
}
} catch (IOException e) {
LOGGER.fatal("Unable to initialize server");
LOGGER.error(e.getMessage());
}
}
}
RequestProcessingTask.java:
package com.ltp.server.core.request;
import java.net.Socket;
import java.util.concurrent.Callable;
import com.ltp.server.core.request.processor.RequestProcessor;
import com.ltp.server.core.request.processor.RequestReaderProcessor;
import lombok.RequiredArgsConstructor;
#RequiredArgsConstructor
public class RequestProcessingTask implements Callable<Request> {
private final Socket socket;
#Override
public Request call() throws Exception {
final RequestProcessor processorChain = new RequestReaderProcessor();
final Request request = processorChain.process(null, socket);
System.out.println(request.getUrl());
socket.close();
return request;
}
}
I found a problem when started debugging: My browser sends many duplicates of request instead of sending only one. As i understood it is because of browser tries not to lose the request, another words for safety. So can i filter these requests somehow?

Related

Dockerize rmi application

I'm new to Docker and I would like to put my rmi server on docker and to access it using the client which is local, on the laptop. When the server is not on docker the application works, however when it is on docker, I get a "Connection Refused" error. Below is the code for the server:
import org.modelmapper.ModelMapper;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.context.annotation.Bean;
import org.springframework.validation.annotation.Validated;
import ro.tuc.ds2020.services.MedicationPlanService;
import ro.tuc.ds2020.servinterface.IMedicationService;
import java.rmi.AlreadyBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.util.*;
#SpringBootApplication
#Validated
public class Ds2020Application extends SpringBootServletInitializer {
private int port;
// private Registry registry;
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Ds2020Application.class);
}
public Ds2020Application() throws RemoteException{
this.port = 8889;
Registry registry = null;
try {
registry = LocateRegistry.createRegistry(this.port);
} catch (RemoteException e) {
e.printStackTrace();
}
try {
//MedicationPlanService is the stub // "name",stub
registry.bind(IMedicationService.class.getSimpleName(), new MedicationPlanService());
} catch (RemoteException e) {
e.printStackTrace();
} catch (AlreadyBoundException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
try {
SpringApplication.run(Ds2020Application.class, args);
System.out.println("The server has started.");
} catch (Exception e) {
e.printStackTrace();
}
}
#Bean
public ModelMapper modelMapper() {
return new ModelMapper();
}
}
and client:
package ro.tuc.ds2020.controller;
import ro.tuc.ds2020.DTO.DrugPlanDTO;
import ro.tuc.ds2020.servinterface.IMedicationService;
import ro.tuc.ds2020.view.DisplayTable;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.sql.SQLException;
import java.text.ParseException;
import java.util.ArrayList;
public class ClientController {
private static IMedicationService iMedicationService;
private Registry registry;
private String serverAddress;
private int serverPort;
private DisplayTable displayTable;
public ClientController() throws RemoteException, NotBoundException, SQLException, ParseException {
this.serverAddress = "localhost";
this.serverPort = 8889;
String patientID="334975ea-c90d-4fd2-9a0b-9e2c9f0e4cb9";
//obtain the stub for the registry
registry = LocateRegistry.getRegistry(serverAddress, serverPort);
//obtain stub for remote object from server registry
iMedicationService = (IMedicationService) (registry.lookup(IMedicationService.class.getSimpleName()));
ArrayList<DrugPlanDTO> dto= iMedicationService.getAllMedicationPlans(patientID);
for (DrugPlanDTO drugplans:
dto) {
System.out.println((String)drugplans.getBegin_time());
}
this.displayTable=new DisplayTable(dto,patientID);
System.out.println("Finished");
}
public static void sendMessage(String drugPlanID,String patientID,String medicationName,String begin_time,String end_time) throws RemoteException, SQLException {
if (iMedicationService != null) {
iMedicationService.savePillTakenLog(drugPlanID,patientID,medicationName,begin_time,end_time);
System.out.println("Finished send message"+ patientID);
}
}
}
Im not sure how to bind the client to the server when dockerizing the application.
Docker compose:
version: '3'
services:
tomcat-db-api:
image: ds_a3
ports:
- "8889:8889"
rabbitmq-container:
image: rabbitmq:management
ports:
- 5672:5672
- 15672:15672
Try setting the: this.serverAddress="tomcat-db-api;" at your client.

Something is wrong when I read object sent by socket

I am new to the forum and I need to solve a problem which I do not see the error because the code is very clear
I have 2 projects: Server & client. In both of them I have the serialized class "ClaseServer"
package ser.des;
import java.io.Serializable;
import java.util.ArrayList;
public class ClaseServidor implements Serializable{
private static final long serialVersionUID = -73813883259606471L;
String ip;
int puerto;
ArrayList<String> coleccion;
public ClaseServidor(){
}
public ClaseServidor(String ip, int puerto, ArrayList<String> coleccion) {
super();
this.ip = ip;
this.puerto = puerto;
this.coleccion = coleccion;
}
public String getIp() {
return ip;
}
public void setIp(String ip) {
this.ip = ip;
}
public int getPuerto() {
return puerto;
}
public void setPuerto(int puerto) {
this.puerto = puerto;
}
public ArrayList<String> getColeccion() {
return coleccion;
}
public void setColeccion(ArrayList<String> coleccion) {
this.coleccion = coleccion;
}
}
The class "hiloservidor" that is responsible for receiving requests and where I read the objects sent by the client.
package servidor;
import java.io.BufferedReader;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.SocketException;
import java.util.Scanner;
import java.util.Timer;
import java.util.TimerTask;
import java.util.logging.Level;
import java.util.logging.Logger;
public class hiloservidor extends Thread{
private Socket ss;
private int counter;
public hiloservidor(Socket i,int c){
this.ss=i;
this.counter=c;
}
#Override
public void run(){
try{
boolean done=false;
System.out.println("hello client "+counter);
while(!done){
ObjectInputStream entrada = new ObjectInputStream(ss.getInputStream());
System.out.println("reading....");
ClaseServidor cla = (ClaseServidor) entrada.readObject();
System.out.println("Done");
}
}
catch(Exception e){
}
}
}
And the client class where I send the objects
package ser.des;
import java.io.File;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Scanner;
public class SerDes{
public static void main(String args[]){
try {
boolean salir=false;
int i = 1;
Socket cliente = new Socket("127.0.0.1",4890);
ArrayList<String>coleccion = new ArrayList<String>();
coleccion.add("Libro1");
coleccion.add("Libro2");
coleccion.add("Libro3");
coleccion.add("Libro4");
coleccion.add("Libro5");
coleccion.add("Libro6");
ClaseServidor miServidor = new ClaseServidor( InetAddress.getLocalHost().getHostAddress(),15253,coleccion);
while(salir==false){
ObjectOutputStream msgToServer = new ObjectOutputStream(cliente.getOutputStream());
System.out.println(InetAddress.getLocalHost().getHostAddress());
msgToServer.writeObject(miServidor);
msgToServer.flush();
System.out.println("datos del servidor enviados");
salir = true;
}
}
catch(Exception e){
}
}
}
The problem is in the "readObject" line of the class "hiloservidor".
It may be a class "ClaseServer" problem but I do not see exactly what it is. If you can help me ... Thanks

ISSUES with Monitor folder, consume WebService and send files via FTP Outbound channel

I'm having bad time dealing with a simple application that must monitor a folder for new files, take each file and consume RESTful service ( one of my other apps) and send the response files using spring integration FTP Outbound channel adapter
It has following structure:
Initializer:
package com.ftpoutbound;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.support.SpringBootServletInitializer;
import com.ftpoutbound.client.FtpoutboundApp;
public class ServletInitializer extends SpringBootServletInitializer {
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(FtpoutboundApp.class);
}
}
I define beans in FtpoutboundApp:
package com.ftpoutbound.client;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.springframework.context.ApplicationContext;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.log4j.Logger;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.event.EventListener;
import org.springframework.expression.common.LiteralExpression;
import org.springframework.integration.annotation.Gateway;
import org.springframework.integration.annotation.IntegrationComponentScan;
import org.springframework.integration.annotation.MessagingGateway;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.integration.file.FileNameGenerator;
import org.springframework.integration.file.remote.session.CachingSessionFactory;
import org.springframework.integration.file.remote.session.SessionFactory;
import org.springframework.integration.ftp.outbound.FtpMessageHandler;
import org.springframework.integration.ftp.session.DefaultFtpSessionFactory;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHandler;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.web.client.RestTemplate;
import com.ftpoutbound.monitor.MonitorDirectory;
#Configuration
#SpringBootApplication
#ComponentScan({ "com.ftpoutbound" })
#IntegrationComponentScan
#EnableAutoConfiguration(exclude = { DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class })
#EnableScheduling
public class FtpoutboundApp implements ApplicationContextAware {
final static Logger logger = Logger.getLogger(FtpoutboundApp.class);
#Autowired
private MonitorDirectory monitor;
#Autowired
MyGateway gateway;
#Value("${remotedirectory}")
private String remotedirectory;
#Value("${remotehost}")
private String remotehost;
#Value("${remoteport}")
private int remoteport;
#Value("${remoteuser}")
private String remoteuser;
#Value("${remotepassword}")
private String remotepassword;
#Value("${outbound214sname}")
private String outbound214sname;
public static void main(String[] args) {
SpringApplication.run(FtpoutboundApp.class, args);
}
public void createGateway(File file214) {
try {
gateway.sendToFtp(file214);
file214.delete();
} catch (Exception e) {
logger.error("ERROR APP OUTBOUND\n");
logger.error(e);
}
}
#Bean
public SessionFactory<FTPFile> ftpSessionFactory() {
DefaultFtpSessionFactory sf = new DefaultFtpSessionFactory();
sf.setHost(remotehost);
sf.setPort(remoteport);
sf.setUsername(remoteuser);
sf.setPassword(remotepassword);
return new CachingSessionFactory<FTPFile>(sf);
}
#Bean
#ServiceActivator(inputChannel = "ftpChannel")
public MessageHandler handler() {
FtpMessageHandler handler = new FtpMessageHandler(ftpSessionFactory());
handler.setRemoteDirectoryExpression(new LiteralExpression(remotedirectory));
handler.setFileNameGenerator(new FileNameGenerator() {
#Override
public String generateFileName(Message<?> message) {
String date = new SimpleDateFormat("yyyyMMdd").format(new Date());
String time = new SimpleDateFormat("HHmmssssssss").format(new Date());
return outbound214sname + "." + date + time;
}
});
return handler;
}
#MessagingGateway
public interface MyGateway {
#Gateway(requestChannel = "ftpChannel")
void sendToFtp(File file);
}
#EventListener
public void afterApplicationReady(ApplicationReadyEvent event) {
try {
logger.info("INICIO DE MONITOREO DE ARCHIVOS HG");
monitor.startMonitoring();
} catch (IOException e) {
logger.error("ERROR EN MONITOREO DE FOLDER ENTRADA ARCHIVOS HG:\n" + e);
} catch (InterruptedException e) {
logger.error("INTERRUPCIƓN EN MONITOREO DE FOLDER ENTRADA ARCHIVOS HG:\n" + e);
}
}
#Bean
RestTemplate restTemplate() {
return new RestTemplate();
}
#Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
}
}
The monitor started from the FtpoutboundApp:
I'm using SCHEDULED annotation since Watchservice was not working either
package com.ftpoutbound.monitor;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.ClosedWatchServiceException;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardWatchEventKinds;
import java.nio.file.WatchEvent;
import java.nio.file.WatchKey;
import java.nio.file.WatchService;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import com.ftpoutbound.client.FtpoutboundApp;
import com.ftpoutbound.restfulclient.httpPost;
#Component
public class MonitorDirectory {
final static Logger logger = Logger.getLogger(MonitorDirectory.class);
#Autowired
private httpPost httppost;
#Value("${inboundhgfilesfolder}")
private String inboundhgfilesfolder;
#Value("${inboundhgfilesfolderbak}")
private String inboundhgfilesfolderbak;
#Value("${hglin}")
private String hglin;
#Scheduled(fixedRate = 10000)
public void startMonitoring() throws IOException, InterruptedException {
try {
listFiles();
} catch (Exception e) {
logger.error("ERROR MONITOREANDO FOLDER");
logger.error(e);
}
}
public void listFiles() throws Exception {
File directory = new File(inboundhgfilesfolder);
File[] fList = directory.listFiles();
for (File file : fList) {
String fileName = file.getName();
if (file.isFile()) {
readFile(fileName);
Thread.sleep(1000);
}
}
}
public void readFile(String fileName) throws IOException {
String hgFile = fileName.substring(0, 7);
if (hgFile.equals(hglin)) {
InputStream input = new FileInputStream(inboundhgfilesfolder + fileName);
StringBuilder builder = new StringBuilder();
int ch;
while ((ch = input.read()) != -1) {
builder.append((char) ch);
}
try {
httppost.get214fromRestful(builder.toString());
} catch (Exception e) {
logger.error("ERROR EN POST REQUEST DESDE APP OUTBOUND:\n" + e);
}
}
moveFile(fileName);
}
public void moveFile(String fileName) {
Path source = Paths.get(inboundhgfilesfolder + fileName);
Path newdir = Paths.get(inboundhgfilesfolderbak + fileName);
try {
Files.move(source, newdir);
} catch (IOException e) {
logger.error("ERROR MOVIENDO ARCHIVO:\n" + e);
}
}
}
And the HTTPclient that consumes the RESTful app
package com.ftpoutbound.restfulclient;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
import com.ftpoutbound.client.FtpoutboundApp;
#Component
public class httpPost {
final static Logger logger = Logger.getLogger(httpPost.class);
#Value("${restful214url}")
private String restful214url;
#Value("${outbound214sfolder}")
private String outbound214sfolder;
#Autowired
private FtpoutboundApp ftpoutbound;
public void get214fromRestful(String hgfile) throws Exception {
logger.info("OBTENIENDO 214");
logger.info("DIRECCION" + restful214url);
logger.info("ARCHIVO" + hgfile);
RestTemplate restTemplate = new RestTemplate();
String result = restTemplate.postForObject(restful214url, hgfile, String.class);
File file = createFile214local(result.toString());
logger.info("RESULTADO DE POST:");
logger.info(result.toString());
ftpoutbound.createGateway(file);
}
private File createFile214local(String hgfile) {
logger.info("ESCRIBIENDO 214");
File file = new File(outbound214sfolder + "214.tmp");
try {
file.createNewFile();
FileWriter fw = new FileWriter(file.getAbsoluteFile());
BufferedWriter bw = new BufferedWriter(fw);
bw.write(hgfile);
bw.close();
} catch (IOException e) {
logger.error("ERROR ESCRIBIENDO FILE:\n->" + e);
}
return file;
}
}
but the app seems not working, it freezes before consuming the RESTful in:
logger.info("OBTENIENDO 214");
logger.info("DIRECCION" + restful214url);
logger.info("ARCHIVO" + hgfile);
I noticed these lines are printed twice in the log, still not sure if this is a threads issue or what causes the APP to not even finish the deployment in the server, I have another similar App (except that one doesn't consume RESTful) and it works OK, another FTPInbound channel Adapter and it works OK, but I have some days figuring what I'm missing or What's the best way to do this.
Believe me, Help will be extremely appreciated.
The issue was that
my outbound channel configuration class was implementing ApplicationContextAware and it was causing the RestTemplate to freezes the App when consuming my Microservices App, so I changed to extend SpringBootServletInitializer and implement WebApplicationInitializerand it worked.

Errorwhen WriteObject from Server To Socket

Some one help me this this exception when send object from server to client
it is NotSerializableException <<
and i try to solve the error and implements the interface Serializable and same exception >> >>> >
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package test;
import java.io.FileWriter;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
* #author Haz
*/
public class Server {
boolean isRunning = true;
public static final int Port = 500;
public static final String Address = "127.0.0.1";
ObjectOutputStream outToClient;
Socket Client;
ArrayList<ConnectionHandler> Handlers;
HashSet<Socket> Callers;
public Server() throws IOException {
ServerSocket socketSer = new ServerSocket(500);
ExecutorService service = Executors.newFixedThreadPool(50);
Handlers = new ArrayList<>();
Callers = new HashSet<>();
while (isRunning) {
Client = socketSer.accept();
System.out.println("Client Connect on Sever");
ConnectionHandler handler = new ConnectionHandler(Client,socketSer);
Handlers.add(handler);
Callers.add(Client);
SendConnectToAll(Handlers);
}
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) throws IOException {
// TODO code application logic here
new Server();
}
private void SendConnectToAll(ArrayList<ConnectionHandler> Handlers){
try {
outToClient = new ObjectOutputStream(Client.getOutputStream());
outToClient.writeObject(Handlers);
outToClient.flush();
outToClient.close();
} catch (IOException ex) {
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package test;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;
import java.net.Socket;
import java.util.Scanner;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
* #author Haz
*/
public class SocketClient {
Socket Client;
ObjectInputStream inputFromServer;
public SocketClient(String Address,int Port) {
try {
Client = new Socket(Address,Port);
} catch (IOException ex) {
Logger.getLogger(SocketClient.class.getName()).log(Level.SEVERE, null, ex);
}
new Thread(new Runnable(){
#Override
public void run() {
Object temp =null;
try {
inputFromServer = new ObjectInputStream(Client.getInputStream());
temp =inputFromServer.readObject();
while((temp)!=null){
temp = inputFromServer.readObject();
System.out.println(temp);
}
inputFromServer.close();
} catch (IOException ex) {
Logger.getLogger(SocketClient.class.getName()).log(Level.SEVERE, null, ex);
} catch (ClassNotFoundException ex) {
Logger.getLogger(SocketClient.class.getName()).log(Level.SEVERE, null, ex);
}
}
}).start();
}
}
and class ConnectionHandler it is empty but i implements
public class ConnectionHandler implements Runnable,Serializable {
private Socket Client;
private ServerSocket Server;
public ConnectionHandler(Socket Client, ServerSocket Server) {
this.Client = Client;
this.Server = Server;
}
ConnectionHandler is not serializable because it contains references to Socket and ServerSocket, which are not serializable. You would have to write your own serialization and deserialization methods to make it serializable.
However, it doesn't make sense to make it serializable anyway, since it doesn't have any serializable data in it to transmit over the network.

Netty channelRead never called

I've played a bit with netty and followed a video(https://www.youtube.com/watch?v=tsz-assb1X8) to build a chat server and client the server works properly(I tested with telnet and here it works) but the client does not recives data. The channelRead method in ChatClinetHandler.java were never called but the channelReadComplete were called.
ChatClient.java
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.InetSocketAddress;
import java.util.logging.Level;
import java.util.logging.Logger;
public class ChatClient {
public static void main(String args[]) {
try {
new ChatClient(new InetSocketAddress("localhost", 8000)).run();
} catch (Exception ex) {
Logger.getLogger(ChatClient.class.getName()).log(Level.SEVERE, null, ex);
}
}
private final InetSocketAddress server;
public ChatClient(InetSocketAddress server) {
this.server = server;
}
public void run() throws Exception {
EventLoopGroup group = new NioEventLoopGroup();
try {
Bootstrap bootstrap = new Bootstrap()
.group(group)
.channel(NioSocketChannel.class)
.handler(new ChatClientInitializer());
Channel channel = bootstrap.connect(server).sync().channel();
System.out.println("Connected to Server: " + server.toString());
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
while (channel.isActive()) {
String userMessage = in.readLine();
channel.writeAndFlush(userMessage + "\r\n");
if (userMessage.equalsIgnoreCase("bye")) {
group.shutdownGracefully();
break;
}
}
} finally {
group.shutdownGracefully();
}
}
}
ChatClientInitializer.java
import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelPipeline; import io.netty.channel.socket.SocketChannel; import io.netty.handler.codec.DelimiterBasedFrameDecoder; import io.netty.handler.codec.Delimiters; import io.netty.handler.codec.string.StringDecoder; import io.netty.handler.codec.string.StringEncoder;
public class ChatClientInitializer extends ChannelInitializer<SocketChannel> {
#Override
protected void initChannel(SocketChannel c) throws Exception {
ChannelPipeline pipeline = c.pipeline();
pipeline.addLast(new DelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter()));
pipeline.addLast(new StringDecoder());
pipeline.addLast(new StringEncoder());
pipeline.addLast(new ChatClientHandler());
} }
ChatClinetHandler.java
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
public class ChatClientHandler extends ChannelInboundHandlerAdapter {
#Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
System.out.println(msg.toString());
}
#Override
public void exceptionCaught(ChannelHandlerContext ctx,
Throwable cause) {
cause.printStackTrace();
}
}
Sorry my mistake i forgot to send "\r\n" with each message.
Although shim_ claims to have determined that the problem is not sending "\r\n" with each message, I see the need to provide a clarification here.
In ChatClientInitializer.java you see a handler named framer which is a DelimiterBasedFrameDecoder object with a line delimiter in that specific example (More info on DelimiterBasedFrameDecoder can be found here).
So, that means the client is expecting messages that ends with "\r\n" on that specific channel. If a message not ending with "\r\n" is received, then the channelRead() method will not be provoked.

Categories

Resources