All Projects → luohaha → Lightcomm4j

luohaha / Lightcomm4j

Licence: agpl-3.0
Yet another lightweight asynchronous network library for java

Programming Languages

java
68154 projects - #9 most used programming language

Projects that are alternatives of or similar to Lightcomm4j

Embassy
Super lightweight async HTTP server library in pure Swift runs in iOS / MacOS / Linux
Stars: ✭ 440 (+1660%)
Mutual labels:  asynchronous, lightweight
Esa Restlight
ESA Restlight is a lightweight and rest-oriented web framework.
Stars: ✭ 67 (+168%)
Mutual labels:  asynchronous, lightweight
Maquette
Pure and simple virtual DOM library
Stars: ✭ 729 (+2816%)
Mutual labels:  lightweight
Blockly Gamepad
A Blockly extension designed to develop games (made with love ❤)
Stars: ✭ 18 (-28%)
Mutual labels:  asynchronous
React Final Form
🏁 High performance subscription-based form state management for React
Stars: ✭ 6,781 (+27024%)
Mutual labels:  asynchronous
Future
🚀 R package: future: Unified Parallel and Distributed Processing in R for Everyone
Stars: ✭ 735 (+2840%)
Mutual labels:  asynchronous
Utox
µTox the lightest and fluffiest Tox client
Stars: ✭ 820 (+3180%)
Mutual labels:  lightweight
Pcp
Performance Co-Pilot
Stars: ✭ 716 (+2764%)
Mutual labels:  lightweight
Cxxhttp
Asynchronous, Header-only C++ HTTP-over-(TCP|UNIX Socket|STDIO) Library
Stars: ✭ 24 (-4%)
Mutual labels:  asynchronous
Splide
Splide is a lightweight, powerful and flexible slider and carousel, written in pure JavaScript without any dependencies.
Stars: ✭ 786 (+3044%)
Mutual labels:  lightweight
Async Reduce
Reducer for similar simultaneously coroutines
Stars: ✭ 17 (-32%)
Mutual labels:  asynchronous
Sup
A curses threads-with-tags style email client (mailing list: [email protected])
Stars: ✭ 780 (+3020%)
Mutual labels:  lightweight
Easy Php
A Faster Lightweight Full-Stack PHP Framework 🚀
Stars: ✭ 754 (+2916%)
Mutual labels:  lightweight
Reactivemongo
🍃 Non-blocking, Reactive MongoDB Driver for Scala
Stars: ✭ 825 (+3200%)
Mutual labels:  asynchronous
Uplot
📈 A small, fast chart for time series, lines, areas, ohlc & bars
Stars: ✭ 6,808 (+27132%)
Mutual labels:  lightweight
Vue Loadable
⏳ Improve your loading state control with pretty simple methods and helpers.
Stars: ✭ 23 (-8%)
Mutual labels:  asynchronous
Spruce
A lightweight state management layer for Alpine.js. 🌲
Stars: ✭ 720 (+2780%)
Mutual labels:  lightweight
Recoil
Asynchronous coroutines for PHP 7.
Stars: ✭ 765 (+2960%)
Mutual labels:  asynchronous
Asyncrat C Sharp
Open-Source Remote Administration Tool For Windows C# (RAT)
Stars: ✭ 819 (+3176%)
Mutual labels:  asynchronous
Larastrator
All in one - admin panel with tailwindcss and vuejs.
Stars: ✭ 25 (+0%)
Mutual labels:  lightweight

LightComm4J

Yet another asynchronous network library for java

Install

Maven

<dependency>
  <groupId>com.github.luohaha</groupId>
  <artifactId>LightComm4J</artifactId>
  <version>1.0.0</version>
</dependency>

Download jar

download

How to use

  • server-side

First, we need to creates a socket address from a hostname and a port number. And then, we should define some callback function when some event happens. We use ServerParam to store these informations.

ServerParam param = new ServerParam("localhost", 8888);
// set backlog
param.setBacklog(128);
param.setOnAccept(conn -> {
	System.out.println("accept!");
});
param.setOnRead((conn, data) -> {
	System.out.println("read!");
});
param.setOnWrite(conn -> {
	System.out.println("write!");
});
param.setOnClose(conn -> {
	System.out.println("close!");
});
param.setOnReadError((conn, err) -> {
	System.out.println(err.getMessage());
});
param.setOnWriteError((conn, err) -> {
	System.out.println(err.getMessage());
});
param.setOnAcceptError(err -> {
	System.out.println(err.getMessage());
});

OnAccept will be called when accepter return a new connection. OnRead will be called when socket's recv buffer isn't empty. OnWrite will be called at first time when socket's send buffer isn't empty and it will be call just once. When remote side close socket, then OnClose be called, but if we close server side socket first, this function will not be called forever.

Finally, we can start our server using 'ServerParam' and need to decide the size of io thread pool.

// 4 is the io thread pool's size
LightCommServer server = new LightCommServer(param, 4);
server.start();
  • client-side

The usage of client side is similar to server side. First, we also need to create a ClientParam which is just like ServerParam, and define some callback function in it.

ClientParam param = new ClientParam();

param.setOnConnection((conn) -> {
	System.out.println("connect!");
});
param.setOnWrite((conn) -> {
	System.out.println("write");
});
param.setOnRead((conn, data) -> {
	System.out.println("read");
});
param.setOnClose((conn) -> {
	System.out.println("close");
});
param.setOnReadError((conn, err) -> {
	System.out.println(err.getMessage());
});
param.setOnWriteError((conn, err) -> {
	System.out.println(err.getMessage());
});
param.setOnConnError(err -> {
	System.out.println(err.getMessage());
});

OnConnection will be called when connection is built. OnWrite, OnRead and OnClose are as same as server side.

Finally, we can use client to send message.

// 4 is the io thread pool's size 
LightCommClient client = new LightCommClient(4);
client.connect("localhost", 8888, param);
client.connect("localhost", 8889, param);

Interface

  • OnAccept
public interface OnAccept {
	public void onAccept(Conn connection);
}
  • OnClose
public interface OnClose {
	public void onClose(Conn connection);
}
  • OnConnection
public interface OnConnection {
	public void onConnection(Conn connection);
}
  • OnRead
public interface OnRead {
	public void onRead(Conn connection, byte[] data);
}
  • OnWrite
public interface OnWrite {
	public void onWrite(Conn connection);
}
  • OnConnError
public interface OnConnError {
	public void onConnError(Exception e);
}
  • OnAcceptError
public interface OnAcceptError {
	public void onAcceptError(Exception e);
}
  • OnReadError
public interface OnReadError {
	public void onReadError(Conn conn, Exception e);
}
  • OnWriteError
public interface OnWriteError {
	public void onWriteError(Conn conn, Exception e);
}
  • Conn

We can send message, close connection and set tcp options by Conn.

public interface Conn {
    // send data to remote side
	public void write(byte[] data) throws ConnectionCloseException, ClosedChannelException;
    // close connection when nothing to send
	public void close() throws IOException;
    // close connection immediately
	public void doClose() throws IOException;
    // get local address
	public SocketAddress getLocalAddress() throws IOException;
    // get remote address
	public SocketAddress getRemoteAddress() throws IOException;
    // set socket's send buffer' size
	public void setSendBuffer(int size) throws IOException;
    // set socket's recv buffer' size
	public void setRecvBuffer(int size) throws IOException;
    // open keep-alive mode
	public void setKeepAlive(boolean flag) throws IOException;
    // open reuse address mode
	public void setReUseAddr(boolean flag) throws IOException;
    // no use nagle algorithm
	public void setNoDelay(boolean flag) throws IOException;
     // get socket's send buffer' size
	public int getSendBuffer() throws IOException;
    // get socket's recv buffer' size
	public int getRecvBuffer() throws IOException;
	public boolean getKeepAlive() throws IOException;
	public boolean getReUseAddr() throws IOException;
	public boolean getNoDelay() throws IOException;
}

How to use rpc

  • server-side

First, we need to create RpcServer, set host address and port. Then we need to add remote call function's name and IRpcFunction. Finally, start server.

RpcServer rpcServer = new RpcServer("localhost", 8888);
rpcServer.add("add", new AddRpc());
rpcServer.start();
public class AddRpc implements IRpcFunction{
    @Override
    public Object rpcCall(String function, List<Object> params) {
        int res = (int)params.get(0) + (int)params.get(1);
        return res;
    }
}
  • client-side

First, we need to create RpcClient, then start it. Then we can use remote and call to finish remote process call.

RpcClient client = new RpcClient();
// need to start client, before remote call.
client.start();
client.remote("localhost", 8888).call("add", 1, 2);

Example

we use LightComm4J to build a simple chatroom.

  • server-side
public class ChatRoomServer {
	public static void main(String[] args) {
		ServerParam param = new ServerParam("localhost", 8888);
		Set<Conn> conns = new HashSet<>();
		param.setBacklog(128);
		param.setOnAccept(conn -> {
			try {
				String m = conn.getRemoteAddress().toString() + " " + "is online!";
				conns.add(conn);
				conns.forEach(c -> {
					try {
						c.write(m.getBytes());
					} catch (Exception e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				});
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		});
		param.setOnRead((conn, msg) -> {
			try {
				String m = conn.getRemoteAddress().toString() + " : " + new String(msg);
				conns.forEach(c -> {
					try {
						c.write(m.getBytes());
					} catch (Exception e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				});
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		});
		param.setOnClose(conn -> {
			try {
				conns.remove(conn);
				String m = conn.getRemoteAddress().toString() + " " + "is offline!";
				conns.forEach(c -> {
					try {
						c.write(m.getBytes());
					} catch (Exception e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				});
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		});
		param.setOnReadError((conn, err) -> {
			System.out.println(err.getMessage());
		});
		param.setOnWriteError((conn, err) -> {
			System.out.println(err.getMessage());
		});
		param.setOnAcceptError(err -> {
			System.out.println(err.getMessage());
		});
		
		LightCommServer server = new LightCommServer(param, 4);
		try {
			server.start();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

  • client-side
public class ChatRoomClient {
	public static void main(String[] args) {
		ClientParam param = new ClientParam();
		param.setOnConnection(conn -> {
			new Thread(() -> {
				Scanner scanner = new Scanner(System.in);
				while (scanner.hasNext()) {
					String msg = scanner.nextLine();
					try {
						conn.write(msg.getBytes());
					} catch (Exception e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}).start();
		});
		param.setOnRead((conn, msg) -> {
			System.out.println("[chatroom] " + new String(msg));
		});
		param.setOnClose(conn -> {
			System.out.println("[chatroom] " + "chatroom close!");
		});
		try {
			LightCommClient client = new LightCommClient(4);
			client.connect("localhost", 8888, param);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

Example for RPC

  • server
public class RpcServerTest {
    public static void main(String[] args) {
        RpcServer rpcServer = new RpcServer("localhost", 8888);
        rpcServer.add("add", new AddRpc());
        rpcServer.start();
    }
}
public class AddRpc implements IRpcFunction{
    @Override
    public Object rpcCall(String function, List<Object> params) {
        int res = (int)params.get(0) + (int)params.get(1);
        return res;
    }
}
  • client
public class RpcClientTest {

    private static RpcClient client = new RpcClient();

    public static int add(int a, int b) {
        return a + b;
    }

    public static int addRpc(int a, int b) {
        return (int)client.remote("localhost", 8888).call("add", a, b);
    }

    public static void main(String[] args) {
        client.start();
        System.out.println("1 + 2 = " + add(1, 2));
        System.out.println("1 + 2 = " + addRpc(1, 2));
    }

}
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].