{
11 | /**
12 | * Handler entry
13 | * @param data callback message data
14 | * @throws Exception unhandled exception
15 | */
16 | void handle(T data) throws Exception;
17 | }
--------------------------------------------------------------------------------
/src/main/java/io/zbus/transport/ErrorHandler.java:
--------------------------------------------------------------------------------
1 | package io.zbus.transport;
2 |
3 | /**
4 | *
5 | * Error callback in networking
6 | *
7 | * @author leiming.hong Jun 27, 2018
8 | *
9 | */
10 | public interface ErrorHandler {
11 | /**
12 | * Handler entry, user should handle all exceptions
13 | *
14 | * @param e error throwed
15 | */
16 | void handle(Throwable e);
17 | }
--------------------------------------------------------------------------------
/src/main/java/io/zbus/transport/EventHandler.java:
--------------------------------------------------------------------------------
1 | package io.zbus.transport;
2 |
3 | /**
4 | * Event handler type, such as Connected/Open, Disconnected/Close event
5 | *
6 | * @author leiming.hong Jun 27, 2018
7 | *
8 | */
9 | public interface EventHandler {
10 | /**
11 | * Handler entry
12 | *
13 | * @throws Exception if any exception unhandled
14 | */
15 | void handle() throws Exception;
16 | }
--------------------------------------------------------------------------------
/src/main/java/io/zbus/transport/IoAdaptor.java:
--------------------------------------------------------------------------------
1 | package io.zbus.transport;
2 |
3 | import java.io.IOException;
4 |
5 | /**
6 | *
7 | * IO event-driven extension points, handling server/client networking events
8 | *
9 | * @author leiming.hong Jun 27, 2018
10 | *
11 | */
12 | public interface IoAdaptor{
13 | /**
14 | * Triggered when session is created
15 | *
16 | * @param sess session object
17 | * @throws IOException if not handled well for IO
18 | */
19 | void sessionCreated(Session sess) throws IOException;
20 | /**
21 | * Triggered when session is trying to close/disconnect
22 | *
23 | * @param sess session object
24 | * @throws IOException if not handled well for IO
25 | */
26 | void sessionToDestroy(Session sess) throws IOException;
27 | /**
28 | * Triggered when underlying session received messages.
29 | *
30 | * Use Session
to write message if write is required
31 | *
32 | * @param msg message decoded from wire
33 | * @param sess session object
34 | * @throws IOException if not handled well for IO
35 | */
36 | void onMessage(Object msg, Session sess) throws IOException;
37 | /**
38 | * Triggered when underlying session encountered an error, such as disconnection violently from remote
39 | *
40 | * @param e exception throwed from underlying session
41 | * @param sess session object
42 | */
43 | void onError(Throwable e, Session sess);
44 | /**
45 | * Triggered when session has been idled for a configured time span.
46 | *
47 | * @param sess session object
48 | * @throws IOException if not handled well for IO
49 | */
50 | void onIdle(Session sess) throws IOException;
51 | }
52 |
--------------------------------------------------------------------------------
/src/main/java/io/zbus/transport/Message.java:
--------------------------------------------------------------------------------
1 | /**
2 | * The MIT License (MIT)
3 | * Copyright (c) 2009-2015 HONG LEIMING
4 | *
5 | * Permission is hereby granted, free of charge, to any person obtaining a copy
6 | * of this software and associated documentation files (the "Software"), to deal
7 | * in the Software without restriction, including without limitation the rights
8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | * copies of the Software, and to permit persons to whom the Software is
10 | * furnished to do so, subject to the following conditions:
11 | *
12 | * The above copyright notice and this permission notice shall be included in
13 | * all copies or substantial portions of the Software.
14 | *
15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | * THE SOFTWARE.
22 | */
23 | package io.zbus.transport;
24 |
25 |
26 | import java.util.HashMap;
27 | import java.util.Map;
28 | import java.util.concurrent.ConcurrentHashMap;
29 |
30 | import com.alibaba.fastjson.JSON;
31 | /**
32 | * Message takes format of standard HTTP:
33 | * key-value headers
34 | *
body of any time which way serialized is controlled in headers's 'content-type' value
35 | *
36 | *
When Message parsed as request, url and method are in use.
37 | *
When Message parsed as response, status of HTTP is in use,
38 | *
39 | * @author leiming.hong Jun 27, 2018
40 | *
41 | */
42 | public class Message {
43 | public static final String ID = "id";
44 |
45 | protected String url;
46 | protected String method;
47 |
48 | protected Integer status; //null: request, otherwise: response
49 | protected String statusText;
50 |
51 | protected Map headers = new ConcurrentHashMap();
52 | protected Object body;
53 |
54 | public Message() {
55 |
56 | }
57 |
58 | public Message(Message msg) {
59 | replace(msg);
60 | this.headers = new HashMap<>(this.headers); //copy headers
61 | }
62 |
63 | public void replace(Message msg) {
64 | this.url = msg.url;
65 | this.method = msg.method;
66 | this.status = msg.status;
67 | this.statusText = msg.statusText;
68 | this.headers = msg.headers;
69 | this.body = msg.body;
70 | }
71 |
72 | public String getUrl(){
73 | return this.url;
74 | }
75 |
76 | public void setUrl(String url) {
77 | this.url = url;
78 | }
79 |
80 | public void setStatus(Integer status) {
81 | this.status = status;
82 | }
83 |
84 | public Integer getStatus(){
85 | return status;
86 | }
87 |
88 | public String getStatusText() {
89 | return statusText;
90 | }
91 |
92 | public void setStatusText(String statusText) {
93 | this.statusText = statusText;
94 | }
95 |
96 | public String getMethod(){
97 | return this.method;
98 | }
99 |
100 | public void setMethod(String method){
101 | this.method = method;
102 | }
103 |
104 | public Map getHeaders() {
105 | return headers;
106 | }
107 |
108 | public void setHeaders(Map headers) {
109 | this.headers = headers;
110 | }
111 |
112 | public String getHeader(String key){
113 | return this.headers.get(key);
114 | }
115 |
116 | public Integer getHeaderInt(String key){
117 | String value = this.headers.get(key);
118 | if(value == null) return null;
119 | return Integer.valueOf(value);
120 | }
121 |
122 | public Long getHeaderLong(String key){
123 | String value = this.headers.get(key);
124 | if(value == null) return null;
125 | return Long.valueOf(value);
126 | }
127 |
128 | public Boolean getHeaderBool(String key){
129 | String value = this.headers.get(key);
130 | if(value == null) return null;
131 | return Boolean.valueOf(value);
132 | }
133 |
134 | public void setHeader(String key, Object value){
135 | if(value == null) return;
136 | this.headers.put(key, value.toString());
137 | }
138 |
139 | public String removeHeader(String key){
140 | return this.headers.remove(key);
141 | }
142 |
143 | public Object getBody() {
144 | return body;
145 | }
146 |
147 | public void setBody(Object body) {
148 | this.body = body;
149 | }
150 |
151 | @Override
152 | public String toString() {
153 | return JSON.toJSONString(this, true);
154 | }
155 | }
--------------------------------------------------------------------------------
/src/main/java/io/zbus/transport/MessageInterceptor.java:
--------------------------------------------------------------------------------
1 | package io.zbus.transport;
2 |
3 | /**
4 | *
5 | * Provides an opportunity to adding/removing info of Message
6 | *
7 | * @author leiming.hong Jun 27, 2018
8 | *
9 | */
10 | public interface MessageInterceptor {
11 | void intercept(Message message);
12 | }
13 |
--------------------------------------------------------------------------------
/src/main/java/io/zbus/transport/ServerAdaptor.java:
--------------------------------------------------------------------------------
1 | package io.zbus.transport;
2 |
3 | import java.io.IOException;
4 | import java.util.Map;
5 | import java.util.concurrent.ConcurrentHashMap;
6 |
7 | import org.slf4j.Logger;
8 | import org.slf4j.LoggerFactory;
9 |
10 | /**
11 | * Base server side IoAdaptor
, handles all IO events except for onMessage.
12 | *
13 | * Subclass ServerAdaptor can take advantage of the sessionTable management in this base class
14 | *
15 | * @author leiming.hong Jun 27, 2018
16 | *
17 | */
18 | public abstract class ServerAdaptor implements IoAdaptor{
19 | private static final Logger logger = LoggerFactory.getLogger(ServerAdaptor.class);
20 | protected Map sessionTable;
21 |
22 | public ServerAdaptor(){
23 | this(new ConcurrentHashMap());
24 | }
25 |
26 | public ServerAdaptor(Map sessionTable){
27 | if(sessionTable == null){
28 | sessionTable = new ConcurrentHashMap();
29 | }
30 | this.sessionTable = sessionTable;
31 | }
32 |
33 | @Override
34 | public void sessionCreated(Session sess) throws IOException {
35 | logger.info("Created: " + sess);
36 | sessionTable.put(sess.id(), sess);
37 | }
38 |
39 | @Override
40 | public void sessionToDestroy(Session sess) throws IOException {
41 | logger.info("Destroyed: " + sess);
42 | cleanSession(sess);
43 | }
44 |
45 | @Override
46 | public void onError(Throwable e, Session sess) {
47 | logger.info("Error: " + sess, e);
48 | try {
49 | cleanSession(sess);
50 | } catch (IOException ex) {
51 | logger.error(ex.getMessage(), ex);
52 | }
53 | }
54 |
55 | @Override
56 | public void onIdle(Session sess) throws IOException {
57 | logger.info("Idled: " + sess);
58 | cleanSession(sess);
59 | }
60 |
61 | protected void cleanSession(Session sess) throws IOException {
62 | try{
63 | sess.close();
64 | } finally {
65 | sessionTable.remove(sess.id());
66 | }
67 | }
68 | }
69 |
70 |
--------------------------------------------------------------------------------
/src/main/java/io/zbus/transport/Session.java:
--------------------------------------------------------------------------------
1 | package io.zbus.transport;
2 |
3 | import java.io.Closeable;
4 |
5 | /**
6 | *
7 | * Session represents a connection between server and client
8 | * It's main function is to write message data to peer side of the session.
9 | *
10 | * Typical session types: TCP, InProc, IPC
11 | *
12 | * @author leiming.hong Jun 27, 2018
13 | *
14 | */
15 | public interface Session extends Closeable {
16 | /**
17 | * @return Id of the session
18 | */
19 | String id();
20 | /**
21 | * @return remote address of the session
22 | */
23 | String remoteAddress();
24 | /**
25 | * @return local address of the session
26 | */
27 | String localAddress();
28 |
29 | /**
30 | * Write data into peer side of the session.
31 | * On the other hand, reading message from session is event-driven in IoAdaptor
32 | * @param msg message object before codec
33 | */
34 | void write(Object msg);
35 |
36 | /**
37 | * @return true if session is active: connected
38 | */
39 | boolean active();
40 |
41 | /**
42 | * Get attached attribute value
43 | * @param key attribute key
44 | * @return attached attribute value
45 | */
46 | V attr(String key);
47 |
48 | /**
49 | * Attach attribute key-value
50 | * @param key attribute key string
51 | * @param value any type of value attached to the session
52 | */
53 | void attr(String key, V value);
54 | }
55 |
--------------------------------------------------------------------------------
/src/main/java/io/zbus/transport/http/WebsocketClient.java:
--------------------------------------------------------------------------------
1 | package io.zbus.transport.http;
2 |
3 | import java.io.IOException;
4 | import java.nio.ByteBuffer;
5 | import java.util.ArrayList;
6 | import java.util.List;
7 |
8 | import org.slf4j.Logger;
9 | import org.slf4j.LoggerFactory;
10 |
11 | import io.zbus.kit.JsonKit;
12 | import io.zbus.transport.AbastractClient;
13 | import io.zbus.transport.DataHandler;
14 | import io.zbus.transport.Message;
15 | import okhttp3.OkHttpClient;
16 | import okhttp3.Request;
17 | import okhttp3.Response;
18 | import okhttp3.WebSocket;
19 | import okhttp3.WebSocketListener;
20 | import okio.ByteString;
21 |
22 | /**
23 | *
24 | * Client of Websocket, via OkHttp3.
25 | *
26 | * @author leiming.hong Jun 27, 2018
27 | *
28 | */
29 | public class WebsocketClient extends AbastractClient {
30 | private static final Logger logger = LoggerFactory.getLogger(WebsocketClient.class);
31 |
32 | public DataHandler onText;
33 | public DataHandler onBinary;
34 |
35 | public long lastActiveTime = System.currentTimeMillis();
36 |
37 | private OkHttpClient client;
38 | private String address;
39 | private WebSocket ws;
40 | private Object wsLock = new Object();
41 |
42 | private List cachedSendingMessages = new ArrayList();
43 |
44 | public WebsocketClient(String address, OkHttpClient client) {
45 | super();
46 |
47 | this.client = client;
48 | if(!address.startsWith("ws://") && !address.startsWith("wss://")) {
49 | address = "ws://" + address;
50 | }
51 | this.address = address;
52 |
53 | onText = msg-> {
54 | Message response = JsonKit.parseObject(msg, Message.class);
55 | if(onMessage != null) {
56 | onMessage.handle(response);
57 | }
58 | };
59 |
60 | //TODO onBinary
61 |
62 | onClose = ()-> {
63 | synchronized (wsLock) {
64 | if(ws != null){
65 | ws.close(1000, null);
66 | ws = null;
67 | }
68 | };
69 |
70 | try {
71 | logger.info("Trying to reconnect " + WebsocketClient.this.address);
72 | Thread.sleep(reconnectDelay);
73 | } catch (InterruptedException e) {
74 | // ignore
75 | }
76 | connect();
77 | };
78 |
79 | onError = e -> {;
80 | if(onClose != null){
81 | try {
82 | onClose.handle();
83 | } catch (Exception ex) {
84 | logger.error(ex.getMessage(), ex);
85 | }
86 | }
87 | };
88 | }
89 |
90 | public WebsocketClient(String address){
91 | this(address, new OkHttpClient());
92 | }
93 |
94 | @Override
95 | protected void sendMessage0(Message data) {
96 | sendMessage(JsonKit.toJSONString(data));
97 | }
98 |
99 | @Override
100 | public void close() throws IOException {
101 | super.close();
102 |
103 | synchronized (this.wsLock) {
104 | if(this.ws != null){
105 | this.ws.close(1000, null);
106 | this.ws = null;
107 | }
108 | }
109 | }
110 |
111 | public void sendMessage(String command){
112 | synchronized (wsLock) {
113 | if(this.ws == null){
114 | this.cachedSendingMessages.add(command);
115 | this.connect();
116 | return;
117 | }
118 | this.ws.send(command);
119 | }
120 | }
121 |
122 | public synchronized void connect(){
123 | connectUnsafe();
124 | }
125 |
126 | protected void connectUnsafe(){
127 | lastActiveTime = System.currentTimeMillis();
128 | Request request = new Request.Builder()
129 | .url(address)
130 | .build();
131 |
132 | this.ws = client.newWebSocket(request, new WebSocketListener() {
133 | @Override
134 | public void onOpen(WebSocket webSocket, Response response) {
135 | String msg = String.format("Websocket(%s) connected", address);
136 | logger.info(msg);
137 | response.close();
138 |
139 | if(cachedSendingMessages.size()>0){
140 | for(String json : cachedSendingMessages){
141 | sendMessage(json);
142 | }
143 | cachedSendingMessages.clear();
144 | }
145 | if(onOpen != null){
146 | runner.submit(()->{
147 | try {
148 | onOpen.handle();
149 | } catch (Exception e) {
150 | logger.error(e.getMessage(), e);
151 | }
152 | });
153 | }
154 | }
155 |
156 | @Override
157 | public void onMessage(WebSocket webSocket, String text) {
158 | lastActiveTime = System.currentTimeMillis();
159 | try {
160 | if(onText != null){
161 | onText.handle(text);
162 | }
163 | } catch (Exception e) {
164 | logger.error(e.getMessage(), e);
165 | }
166 | }
167 |
168 | @Override
169 | public void onMessage(WebSocket webSocket, ByteString bytes) {
170 | lastActiveTime = System.currentTimeMillis();
171 | try {
172 | if(onBinary != null){
173 | onBinary.handle(bytes.asByteBuffer());
174 | }
175 | } catch (Exception e) {
176 | logger.error(e.getMessage(), e);
177 | }
178 | }
179 |
180 | @Override
181 | public void onClosed(WebSocket webSocket, int code, String reason) {
182 | String msg = String.format("Websocket(%s) closed", address);
183 | logger.info(msg);
184 | if(onClose != null){
185 | try {
186 | onClose.handle();
187 | } catch (Exception e) {
188 | logger.error(e.getMessage(), e);
189 | }
190 | }
191 | }
192 |
193 | @Override
194 | public void onFailure(WebSocket webSocket, Throwable t, Response response) {
195 | String error = String.format("Websocket(%s) error: %s", address, t.getMessage());
196 | logger.error(error);
197 | if(response != null) {
198 | response.close();
199 | }
200 | if(onError != null){
201 | onError.handle(t);
202 | }
203 | }
204 | });
205 | }
206 | }
207 |
--------------------------------------------------------------------------------
/src/main/java/io/zbus/transport/inproc/InProcClient.java:
--------------------------------------------------------------------------------
1 | package io.zbus.transport.inproc;
2 |
3 | import java.io.IOException;
4 | import java.util.concurrent.ConcurrentHashMap;
5 | import java.util.concurrent.ConcurrentMap;
6 |
7 | import org.slf4j.Logger;
8 | import org.slf4j.LoggerFactory;
9 |
10 | import io.zbus.kit.StrKit;
11 | import io.zbus.transport.AbastractClient;
12 | import io.zbus.transport.IoAdaptor;
13 | import io.zbus.transport.Message;
14 | import io.zbus.transport.Session;
15 |
16 | /**
17 | *
18 | * Client of In-Process, optimized for speed.
19 | *
20 | * Crucial ideas:
21 | * 1) InprocClient is a Session type, can be plugged into IoAdaptor
from server, which is event driven.
22 | *
2) write message in process means directly invoking onMessage of the client.
23 | *
3) send message to peer means directly invoking server's IoAdaptor
's onMessage
24 | *
25 | * @author leiming.hong Jun 27, 2018
26 | *
27 | */
28 | public class InprocClient extends AbastractClient implements Session {
29 | private static final Logger logger = LoggerFactory.getLogger(InprocClient.class);
30 | private ConcurrentMap attributes = null;
31 |
32 | private IoAdaptor ioAdaptor;
33 | private final String id = StrKit.uuid();
34 | private boolean active = false;
35 | private Object lock = new Object();
36 |
37 | public InprocClient(IoAdaptor ioAdaptor) {
38 | this.ioAdaptor = ioAdaptor;
39 |
40 | }
41 |
42 | @Override
43 | public void connect() {
44 | synchronized (lock) {
45 | if(active) return;
46 | }
47 | active = true;
48 | try {
49 | ioAdaptor.sessionCreated(this);
50 | if(onOpen != null) {
51 | runner.submit(()->{
52 | try {
53 | onOpen.handle();
54 | } catch (Exception e) {
55 | logger.error(e.getMessage(), e);
56 | }
57 | });
58 | }
59 | } catch (Exception e) {
60 | logger.error(e.getMessage(), e);
61 | }
62 | }
63 |
64 | @Override
65 | public void close() throws IOException {
66 | super.close();
67 |
68 | active = false;
69 | ioAdaptor.sessionToDestroy(this);
70 | }
71 |
72 | @Override
73 | public String id() {
74 | return id;
75 | }
76 |
77 | @Override
78 | public String remoteAddress() {
79 | return "InprocServer";
80 | }
81 |
82 | @Override
83 | public String localAddress() {
84 | return "Inproc-"+id;
85 | }
86 |
87 |
88 | @Override
89 | public void write(Object msg) { //Session received message
90 | try {
91 | if(!(msg instanceof Message)) {
92 | logger.error("Message type required");
93 | return;
94 | }
95 | Message data = (Message)msg;
96 | if(onMessage != null) {
97 | onMessage.handle(data);
98 | }
99 | } catch (Exception e) {
100 | logger.error(e.getMessage(), e);
101 | }
102 | }
103 |
104 | @Override
105 | protected void sendMessage0(Message data) { //Session send out message
106 | synchronized (lock) {
107 | if(!active) {
108 | connect();
109 | }
110 | }
111 |
112 | try {
113 | ioAdaptor.onMessage(data, this);
114 | } catch (IOException e) {
115 | logger.error(e.getMessage(), e);
116 | }
117 | }
118 |
119 | @Override
120 | public boolean active() {
121 | return active;
122 | }
123 |
124 | @SuppressWarnings("unchecked")
125 | public V attr(String key) {
126 | if (this.attributes == null) {
127 | return null;
128 | }
129 |
130 | return (V) this.attributes.get(key);
131 | }
132 |
133 | public void attr(String key, V value) {
134 | if(value == null){
135 | if(this.attributes != null){
136 | this.attributes.remove(key);
137 | }
138 | return;
139 | }
140 | if (this.attributes == null) {
141 | synchronized (this) {
142 | if (this.attributes == null) {
143 | this.attributes = new ConcurrentHashMap();
144 | }
145 | }
146 | }
147 | this.attributes.put(key, value);
148 | }
149 |
150 | @Override
151 | public String toString() {
152 | return localAddress();
153 | }
154 | }
155 |
--------------------------------------------------------------------------------
/src/main/java/io/zbus/transport/ipc/IpcClient.java:
--------------------------------------------------------------------------------
1 | package io.zbus.transport.ipc;
2 |
3 | /**
4 | *
5 | * Inter-Process-Communication client
6 | *
7 | * Not implemented yet
8 | *
9 | * @author leiming.hong Jun 27, 2018
10 | *
11 | */
12 | public class IpcClient {
13 |
14 | }
15 |
--------------------------------------------------------------------------------
/src/main/resources/static/base.css:
--------------------------------------------------------------------------------
1 | .navbar-brand {
2 | padding-top: 8px;
3 | }
4 | .navbar-brand > img {
5 | width: 36px;
6 | height: 36px;
7 | display: inline;
8 | }
9 |
10 | .navbar-brand > span {
11 | color: rgb(145, 220, 90);
12 | font-weight: bold;
13 | visibility: visible;
14 | display: inline-block;
15 | clear: both;
16 | font-size: 24px;
17 | line-height: 24px;
18 | white-space: nowrap;
19 | position: relative;
20 | padding: 0px;
21 | top: 4px;
22 | }
23 | .topic {
24 | margin: 3px;
25 | }
26 |
27 |
28 | .filter-box{
29 | float: right;
30 | clear: right;
31 | padding-top: 1px;
32 | }
33 | textarea.log {
34 | border-style: none;
35 | border-color: Transparent;
36 | overflow: auto;
37 | resize: none;
38 | }
39 |
40 | .label-as-badge{
41 | border-radius: 3em;
42 | padding-left: 6px;
43 | padding-right: 6px;
44 | }
45 | .topic-deactive{
46 | color: black;
47 | background-color: white;
48 | }
49 |
50 | .badge-deactive{
51 | color: black;
52 | background-color: #777;
53 | }
54 | .add-topic-modal{
55 | width: 400px;
56 | }
57 | .add-topic-content{
58 | margin-left: 32px;
59 | margin-right: 32px;
60 | margin-top: 8px;
61 | margin-bottom: 16px;
62 | }
63 | .add-topic-content div{
64 | margin-top: 6px;
65 | }
66 | input.topic-item{
67 | width: 220px;
68 | }
69 | .target{
70 | margin-top: 0px;
71 | }
72 | .close-box{
73 | float: right;
74 | clear: right;
75 | }
76 |
77 | .action {
78 | margin: 6px;
79 | padding: 6px;
80 | cursor: pointer;
81 | }
82 | .action-list {
83 | margin: 8px;
84 | }
85 | .modal-header{
86 | padding: 10px;
87 | }
88 | .modal {
89 | text-align: center;
90 | }
91 |
92 | @media screen and (min-width: 768px) {
93 | .modal:before {
94 | display: inline-block;
95 | vertical-align: middle;
96 | content: " ";
97 | height: 100%;
98 | }
99 | }
100 |
101 | .modal-dialog {
102 | display: inline-block;
103 | text-align: left;
104 | vertical-align: middle;
105 | }
106 |
107 |
108 | .caption{
109 | margin-left: 6px;
110 | display: inline;
111 | }
112 | .caption span{
113 | font-weight: bolder;
114 | }
115 |
116 | .consumer-group-list {
117 | overflow-y: auto;
118 | }
119 |
120 |
121 | .table-outter{
122 | border: 2px solid #ddd;
123 | margin: 0px;
124 | width: 100%;
125 | max-width: 100%;
126 | }
127 | .table-outter>tbody>tr{
128 | border-bottom: 2px solid #ddd;
129 | }
130 |
131 | .table-outter>tbody>tr>td{
132 | border-right: 2px solid #ddd;
133 | }
134 |
135 |
136 | .table-nested{
137 | margin: 0px;
138 | width: 100%;
139 | max-width: 100%;
140 | }
141 |
142 | .table-nested>tbody>tr{
143 | border-bottom: 1px solid #ddd;
144 | line-height: 24px;
145 | }
146 | .table-nested>tbody>tr:last-child{
147 | border: none;
148 | }
149 | .table-nested>tbody>tr>td{
150 | border-right: 1px solid #ddd;
151 | }
152 | .table-nested>tbody>tr>td:last-child{
153 | border: none;
154 | }
155 |
156 | .table-nested>tbody>tr>td,
157 | .table-nested>tfoot>tr>td,
158 | .table-nested>tfoot>tr>th,
159 | .table-nested>thead>tr>td,
160 | .table-nested>thead>tr>th {
161 | padding: 0px;
162 | vertical-align: middle;
163 | }
164 |
165 | .tgroup tr>td:nth-child(1) {
166 | width: 12%;
167 | }
168 | .tgroup tr>td:nth-child(2) {
169 | width: 88%;
170 | }
171 |
172 |
173 | .sgroup tr>td:nth-child(2) {
174 | width: 40%;
175 | }
176 | .sgroup tr>td:nth-child(3) {
177 | width: 60%;
178 | }
179 |
180 | .sgroup td span {
181 | margin-right: 4px;
182 | }
183 |
184 |
185 | .cgroup tr>td:nth-child(1) {
186 | width: 30%;
187 | }
188 | .cgroup tr>td:nth-child(2) {
189 | width: 20%;
190 | }
191 | .cgroup tr>td:nth-child(3) {
192 | width: 10%;
193 | }
194 | .cgroup tr>td:nth-child(4) {
195 | width: 30%;
196 | }
197 | .header-ctrl{
198 | font-weight: bold;
199 | background-color: #f5f5f5;
200 | line-height: 30px;
201 | border-bottom: none;
202 | }
203 |
204 | .op {
205 | float: right;
206 | margin-right: 10px;
207 | }
208 |
209 | .op div {
210 | float: left;
211 | margin-left: 6px;
212 | }
213 |
214 | .op-del {
215 | color: red;
216 | }
217 |
218 | .op2 {
219 | float: left;
220 | margin-left: 10px;
221 | font-weight: bold;
222 | }
223 |
224 | .cap {
225 | float: left;
226 | }
227 |
228 | td div.td {
229 | margin-left: 10px;
230 | float: left;
231 | }
232 |
233 | td div.num{
234 | font-weight: bold;
235 | }
236 |
237 | .login input {
238 | font-size: 16px;
239 | }
240 |
241 | .login .token{
242 | width: 300px;
243 | }
244 |
245 | .hide{
246 | display: none;
247 | }
--------------------------------------------------------------------------------
/src/main/resources/static/base.js:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rushmore/zbus-server/b27bb689599066a8b81f3609a5ce4c903a413b99/src/main/resources/static/base.js
--------------------------------------------------------------------------------
/src/main/resources/static/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rushmore/zbus-server/b27bb689599066a8b81f3609a5ce4c903a413b99/src/main/resources/static/favicon.ico
--------------------------------------------------------------------------------
/src/main/resources/static/home.htm:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | zbus = mq + rpc
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
21 |
22 |
53 |
54 |
55 |
56 |
57 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
108 |
109 |
110 | Topic:
111 |
112 |
113 |
114 | Mask:
115 |
116 |
117 |
118 |
119 |
Servers:
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
Servers:
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
153 |
154 |
155 |
156 |
157 |
--------------------------------------------------------------------------------
/src/main/resources/static/logo.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/main/resources/static/rpc.htm:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {{urlPrefix}} Java
6 |
7 |
32 |
33 |
34 |
35 |
42 |
43 |
44 |
45 | URL={{urlPrefix}}/[module]/[method]/[param1]/[param2]/...
46 |
47 |
48 |
49 |
50 | URL Path |
51 | Return Type |
52 | Method and Params |
53 |
54 |
55 |
56 | {{content}}
57 |
58 |
59 |
60 |
61 |
62 |
63 |
--------------------------------------------------------------------------------
/src/test/java/io/zbus/auth/SignAuthExample.java:
--------------------------------------------------------------------------------
1 | package io.zbus.auth;
2 |
3 | import com.alibaba.fastjson.JSON;
4 |
5 | import io.zbus.kit.JsonKit;
6 | import io.zbus.transport.Message;
7 |
8 | public class SignAuthExample {
9 | public static void main(String[] args) {
10 | ApiKeyProvider apiKeyProvider = new XmlApiKeyProvider("rpc/auth.xml");
11 | RequestAuth auth = new DefaultAuth(apiKeyProvider);
12 |
13 | RequestSign sign = new DefaultSign();
14 |
15 | Message req = new Message();
16 | req.setHeader("cmd", "pub");
17 | req.setHeader("mq", "MyRpc");
18 | req.setHeader("ack", false);
19 |
20 | req.setBody(new Object[] {1,2});
21 |
22 | String apiKey = "2ba912a8-4a8d-49d2-1a22-198fd285cb06";
23 | String secretKey = "461277322-943d-4b2f-b9b6-3f860d746ffd";
24 |
25 | sign.sign(req, apiKey, secretKey);
26 |
27 | String wired = JsonKit.toJSONString(req);
28 | System.out.println(wired);
29 | Message req2 = JsonKit.parseObject(wired, Message.class);
30 | AuthResult res = auth.auth(req2);
31 |
32 | System.out.println(res.success);
33 |
34 | System.out.println(JSON.toJSONString(false));
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/test/java/io/zbus/kit/JsonKitExample.java:
--------------------------------------------------------------------------------
1 | package io.zbus.kit;
2 |
3 | public class JsonKitExample {
4 | public static void main(String[] args) {
5 | String json = "select:[display_name,id],where:{id:1}";
6 | json = JsonKit.fixJson(json);
7 | System.out.println(json);
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/src/test/java/io/zbus/mq/Pub.java:
--------------------------------------------------------------------------------
1 | package io.zbus.mq;
2 |
3 | import java.util.concurrent.TimeUnit;
4 | import java.util.concurrent.atomic.AtomicInteger;
5 |
6 | import io.zbus.transport.Message;
7 |
8 | public class Pub {
9 |
10 | public static MqClient buildInproClient() {
11 | MqServer server = new MqServer(new MqServerConfig());
12 | return new MqClient(server);
13 | }
14 |
15 | @SuppressWarnings("resource")
16 | public static void main(String[] args) throws Exception {
17 | MqClient client = new MqClient("wss://111.230.136.74");
18 |
19 | //MqClient client = buildInproClient();
20 |
21 | client.heartbeat(30, TimeUnit.SECONDS);
22 | final String mq = "MyMQ", mqType = Protocol.MEMORY;
23 |
24 | //1) Create MQ if necessary
25 | Message req = new Message();
26 | req.setHeader("cmd", "create"); //Create
27 | req.setHeader("mq", mq);
28 | req.setHeader("mqType", mqType); //disk|memory|db
29 |
30 | client.invoke(req);
31 |
32 | AtomicInteger count = new AtomicInteger(0);
33 | for (int i = 0; i < 100; i++) {
34 | //2) Publish Message
35 | Message msg = new Message();
36 | msg.setHeader("cmd", "pub"); //Publish
37 | msg.setHeader("mq", mq);
38 | msg.setBody(i); //set business data in body
39 |
40 | client.invoke(msg, res->{ //async call
41 | if(count.getAndIncrement() % 10000 == 0) {
42 | System.out.println(res);
43 | }
44 | });
45 | }
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/test/java/io/zbus/mq/Sub.java:
--------------------------------------------------------------------------------
1 | package io.zbus.mq;
2 |
3 | import java.util.concurrent.TimeUnit;
4 |
5 | import io.zbus.transport.Message;
6 |
7 | public class Sub {
8 | public static MqClient buildInproClient() {
9 | MqServer server = new MqServer(new MqServerConfig());
10 | return new MqClient(server);
11 | }
12 |
13 | @SuppressWarnings("resource")
14 | public static void main(String[] args) throws Exception {
15 | MqClient client = new MqClient("localhost:15555");
16 | //MqClient client = buildInproClient();
17 |
18 | client.heartbeat(30, TimeUnit.SECONDS);
19 |
20 | final String mq = "MyMQ", channel = "MyChannel", mqType = Protocol.MEMORY;
21 |
22 | client.addMqHandler(mq, channel, 4, data->{
23 | System.out.println(data);
24 | });
25 |
26 | client.onOpen(()->{
27 | Message req = new Message();
28 | req.setHeader("cmd", "create"); //create MQ/Channel
29 | req.setHeader("mq", mq);
30 | req.setHeader("mqType", mqType);
31 | req.setHeader("channel", channel);
32 | Message res = client.invoke(req);
33 | System.out.println(res);
34 |
35 | Message sub = new Message();
36 | sub.setHeader("cmd", "sub"); //Subscribe on MQ/Channel
37 | sub.setHeader("mq", mq);
38 | sub.setHeader("channel", channel);
39 | sub.setHeader("window", 1);
40 | sub.setHeader("filter", "abc");
41 |
42 | client.invoke(sub, data->{
43 | System.out.println(data);
44 | });
45 | });
46 |
47 | client.connect();
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/test/java/io/zbus/mq/Take.java:
--------------------------------------------------------------------------------
1 | package io.zbus.mq;
2 |
3 | import io.zbus.transport.Message;
4 |
5 | public class Take {
6 |
7 | public static MqClient buildInproClient() {
8 | MqServer server = new MqServer(new MqServerConfig());
9 | return new MqClient(server);
10 | }
11 |
12 | public static void main(String[] args) throws Exception {
13 | MqClient client = new MqClient("localhost:15555");
14 | //MqClient client = buildInproClient();
15 |
16 | final String mq = "MyMQ", channel = "MyChannel";
17 |
18 | Message req = new Message();
19 | req.setHeader("cmd", "take");
20 | req.setHeader("mq", mq);
21 | req.setHeader("channel", channel);
22 |
23 | client.invoke(req, res->{
24 | System.out.println(res);
25 |
26 | client.close();
27 | }, e->{
28 | e.printStackTrace();
29 | try { client.close(); } catch (Exception ex) { }
30 | });
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/test/java/io/zbus/mq/Zbus.java:
--------------------------------------------------------------------------------
1 | package io.zbus.mq;
2 |
3 | public class Zbus {
4 | public static void main(String[] args) {
5 | MqServer.main(args);
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/src/test/java/io/zbus/mq/inproc/Pub.java:
--------------------------------------------------------------------------------
1 | package io.zbus.mq.inproc;
2 |
3 | import java.util.concurrent.atomic.AtomicInteger;
4 |
5 | import io.zbus.mq.MqClient;
6 | import io.zbus.mq.MqServer;
7 | import io.zbus.mq.MqServerConfig;
8 | import io.zbus.transport.Message;
9 |
10 | public class Pub {
11 |
12 | @SuppressWarnings("resource")
13 | public static void main(String[] args) throws Exception {
14 | MqServer server = new MqServer(new MqServerConfig());
15 |
16 | MqClient client = new MqClient(server);
17 |
18 | String mq = "MyMQ";
19 |
20 | Message create = new Message();
21 | create.setHeader("cmd", "create");
22 | create.setHeader("mq", mq);
23 | create.setHeader("mqType", "disk");
24 | client.invoke(create, res->{
25 | System.out.println(res);
26 | });
27 | Thread.sleep(100);
28 |
29 | AtomicInteger count = new AtomicInteger(0);
30 | for (int i = 0; i < 200000; i++) {
31 | Message msg = new Message();
32 | msg.setHeader("cmd", "pub"); //Publish
33 | msg.setHeader("mq", mq);
34 | msg.setBody(i);
35 |
36 | client.invoke(msg, res->{
37 | if(count.getAndIncrement() % 10000 == 0) {
38 | System.out.println(res);
39 | }
40 | });
41 | }
42 | //ws.close();
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/test/java/io/zbus/mq/inproc/Sub.java:
--------------------------------------------------------------------------------
1 | package io.zbus.mq.inproc;
2 |
3 | import java.util.concurrent.TimeUnit;
4 | import java.util.concurrent.atomic.AtomicInteger;
5 |
6 | import io.zbus.mq.MqClient;
7 | import io.zbus.mq.MqServer;
8 | import io.zbus.mq.MqServerConfig;
9 | import io.zbus.transport.Message;
10 |
11 | public class Sub {
12 |
13 | @SuppressWarnings({ "resource" })
14 | public static void main(String[] args) throws Exception {
15 | MqServer server = new MqServer(new MqServerConfig());
16 | MqClient client = new MqClient(server);
17 | client.heartbeat(30, TimeUnit.SECONDS);
18 |
19 | final String mq = "MyMQ", channel = "MyChannel";
20 | AtomicInteger count = new AtomicInteger(0);
21 | client.addMqHandler(mq, channel, data->{
22 | if(count.getAndIncrement() % 10000 == 0) {
23 | System.out.println(data);
24 | }
25 | });
26 |
27 | client.onOpen(()->{
28 | Message req = new Message();
29 | req.setHeader("cmd", "create"); //create MQ/Channel
30 | req.setHeader("mq", mq);
31 | req.setHeader("mqType", "disk"); //Set as Disk type
32 | req.setHeader("channel", channel);
33 | client.invoke(req, res->{
34 | System.out.println(res);
35 | });
36 |
37 | Message sub = new Message();
38 | sub.setHeader("cmd", "sub"); //Subscribe on MQ/Channel
39 | sub.setHeader("mq", mq);
40 | sub.setHeader("channel", channel);
41 | client.invoke(sub, res->{
42 | System.out.println(res);
43 | });
44 | });
45 |
46 | client.connect();
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/test/java/io/zbus/net/http/HttpClientExample.java:
--------------------------------------------------------------------------------
1 | package io.zbus.net.http;
2 |
3 | import io.zbus.transport.Message;
4 |
5 | public class HttpClientExample {
6 |
7 | public static void main(String[] args) throws Exception {
8 | HttpClient client = new HttpClient();
9 | Message message = new Message();
10 | message.setUrl("https://test.io");
11 | String res = client.string(message);
12 | System.out.println(res);
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/test/java/io/zbus/net/http/HttpServerExample.java:
--------------------------------------------------------------------------------
1 | package io.zbus.net.http;
2 |
3 | import java.io.IOException;
4 |
5 | import io.zbus.transport.Message;
6 | import io.zbus.transport.Server;
7 | import io.zbus.transport.ServerAdaptor;
8 | import io.zbus.transport.Session;
9 | import io.zbus.transport.http.HttpWsServer;
10 |
11 | public class HttpServerExample {
12 |
13 | @SuppressWarnings("resource")
14 | public static void main(String[] args) {
15 |
16 | ServerAdaptor adaptor = new ServerAdaptor() {
17 | @Override
18 | public void onMessage(Object msg, Session sess) throws IOException {
19 | Message res = new Message();
20 | res.setStatus(200);
21 |
22 | res.setHeader("id", res.getHeader("id"));
23 | res.setHeader("content-type", "text/plain; charset=utf8");
24 |
25 | res.setBody("中文"+System.currentTimeMillis());
26 |
27 | sess.write(res);
28 | }
29 | };
30 |
31 | Server server = new HttpWsServer();
32 | server.start(80, adaptor);
33 | //server.start(8080, adaptor); //You may start 80 and 8080 together!
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/test/java/io/zbus/net/ssl/SslServerExample.java:
--------------------------------------------------------------------------------
1 | package io.zbus.net.ssl;
2 |
3 | import java.io.IOException;
4 |
5 | import io.netty.handler.ssl.SslContext;
6 | import io.zbus.transport.Message;
7 | import io.zbus.transport.Server;
8 | import io.zbus.transport.ServerAdaptor;
9 | import io.zbus.transport.Session;
10 | import io.zbus.transport.Ssl;
11 | import io.zbus.transport.http.HttpWsServer;
12 |
13 | public class SslServerExample {
14 |
15 | @SuppressWarnings("resource")
16 | public static void main(String[] args) {
17 |
18 | SslContext context = Ssl.buildServerSsl("ssl/zbus.crt", "ssl/zbus.key");
19 |
20 | Server server = new HttpWsServer();
21 | ServerAdaptor adaptor = new ServerAdaptor() {
22 | @Override
23 | public void onMessage(Object msg, Session sess) throws IOException {
24 | Message res = new Message();
25 | res.setStatus(200);
26 | res.setHeader("content-type", "text/html; charset=utf8");
27 | res.setBody("hello world
");
28 |
29 | sess.write(res);
30 | }
31 | };
32 | server.start(8080, adaptor, context);
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/test/java/io/zbus/net/ws/WebSocketExample.java:
--------------------------------------------------------------------------------
1 | package io.zbus.net.ws;
2 |
3 | import java.util.HashMap;
4 | import java.util.Map;
5 |
6 | import io.zbus.transport.Message;
7 | import io.zbus.transport.http.WebsocketClient;
8 |
9 | public class WebSocketExample {
10 |
11 | public static void main(String[] args) throws Exception {
12 |
13 | WebsocketClient ws = new WebsocketClient("wss://zbus.io");
14 | ws.onText = data -> {
15 | System.out.println(data);
16 | ws.close();
17 | };
18 |
19 | ws.onOpen(()->{
20 | Map command = new HashMap<>();
21 | command.put("module", "example");
22 | command.put("method", "echo");
23 | command.put("params", new Object[] {"hong"});
24 |
25 | Message message = new Message();
26 | message.setBody(command);
27 |
28 | //for MQ
29 | message.setHeader("cmd", "pub");
30 | message.setHeader("mq", "MyMQ");
31 | message.setHeader("ack", false);
32 |
33 | ws.sendMessage(message);
34 |
35 | });
36 |
37 | ws.connect();
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/test/java/io/zbus/rpc/GenericService.java:
--------------------------------------------------------------------------------
1 | package io.zbus.rpc;
2 |
3 | import java.util.HashMap;
4 | import java.util.Map;
5 |
6 | public class GenericService implements MethodInvoker {
7 |
8 | @Override
9 | public Object invoke(String funcName, Map params) {
10 | Map res = new HashMap<>();
11 | res.put("invokedFunc", funcName);
12 | res.put("invokedParams", params);
13 | return res;
14 | }
15 | }
--------------------------------------------------------------------------------
/src/test/java/io/zbus/rpc/MyRegisterInterceptor.java:
--------------------------------------------------------------------------------
1 | package io.zbus.rpc;
2 |
3 | import java.util.Arrays;
4 | import java.util.Map;
5 |
6 | public class MyRegisterInterceptor implements RpcStartInterceptor {
7 |
8 | @Override
9 | public void onStart(RpcProcessor processor) {
10 | //注册方法
11 | GenericService service = new GenericService();
12 |
13 | //抽象的服务调用,增加一个具体的方法
14 | RpcMethod spec = new RpcMethod();
15 | spec.method = "func1";
16 | spec.paramTypes = Arrays.asList(String.class.getName(), Integer.class.getName());
17 | spec.paramNames = Arrays.asList("name", "age");
18 | spec.returnType = Map.class.getName();
19 |
20 | processor.mount(spec, service);
21 | }
22 | }
--------------------------------------------------------------------------------
/src/test/java/io/zbus/rpc/RpcClientDirect.java:
--------------------------------------------------------------------------------
1 | package io.zbus.rpc;
2 |
3 | public class RpcClientDirect {
4 |
5 | public static void main(String[] args) throws Exception {
6 | RpcClient rpc = new RpcClient("localhost:8080");
7 | //rpc.setAuthEnabled(true);
8 | //rpc.setApiKey("2ba912a8-4a8d-49d2-1a22-198fd285cb06");
9 | //rpc.setSecretKey("461277322-943d-4b2f-b9b6-3f860d746ffd");
10 |
11 | TestCases.doTest(rpc, "/example");
12 |
13 | rpc.close();
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/test/java/io/zbus/rpc/RpcClientInproc.java:
--------------------------------------------------------------------------------
1 | package io.zbus.rpc;
2 |
3 | import java.util.concurrent.atomic.AtomicInteger;
4 |
5 | import io.zbus.rpc.biz.InterfaceExampleImpl;
6 | import io.zbus.transport.Message;
7 | import io.zbus.transport.inproc.InprocClient;
8 |
9 | public class RpcClientInproc {
10 |
11 | @SuppressWarnings("resource")
12 | public static void main(String[] args) throws Exception {
13 | RpcProcessor p = new RpcProcessor();
14 | p.mount("example", InterfaceExampleImpl.class);
15 |
16 | RpcServer server = new RpcServer(p);
17 | server.start();
18 |
19 | InprocClient rpc = new InprocClient(server.getServerAdaptor());
20 |
21 | AtomicInteger count = new AtomicInteger(0);
22 | for (int i = 0; i < 1000000; i++) {
23 | Message req = new Message();
24 | req.setUrl("/example/getOrder");
25 |
26 | rpc.invoke(req, res->{
27 | int c = count.getAndIncrement();
28 | if(c % 10000 == 0) {
29 | System.out.println(c + ": " + res);
30 | }
31 | });
32 | }
33 | //rpc.close();
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/test/java/io/zbus/rpc/RpcClientMQ.java:
--------------------------------------------------------------------------------
1 | package io.zbus.rpc;
2 |
3 | public class RpcClientMQ {
4 |
5 | public static void main(String[] args) throws Exception {
6 | RpcClient rpc = new RpcClient("localhost:15555");
7 |
8 | //rpc.setAuthEnabled(true);
9 | //rpc.setApiKey("2ba912a8-4a8d-49d2-1a22-198fd285cb06");
10 | //rpc.setSecretKey("461277322-943d-4b2f-b9b6-3f860d746ffd");
11 |
12 |
13 | TestCases.doTest(rpc, "/example");
14 |
15 | rpc.close();
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/test/java/io/zbus/rpc/RpcServerDirectHttp.java:
--------------------------------------------------------------------------------
1 | package io.zbus.rpc;
2 |
3 | import java.util.HashMap;
4 | import java.util.Map;
5 |
6 | import io.zbus.kit.FileKit;
7 | import io.zbus.rpc.annotation.RequestMapping;
8 | import io.zbus.transport.Message;
9 |
10 | public class RpcServerDirectHttp {
11 | private FileKit fileKit = new FileKit(false);
12 |
13 | @RequestMapping("/")
14 | public Message home() {
15 | Message res = new Message();
16 | res.setStatus(200);
17 | res.setHeader("content-type", "text/html; charset=utf8");
18 | res.setBody("home page
");
19 |
20 | return res;
21 | }
22 |
23 | @RequestMapping("/showUpload")
24 | public Message showUpload() {
25 | return fileKit.loadResource("page/upload.html");
26 | }
27 |
28 | @RequestMapping("/upload")
29 | public Message doUpload(Message req) {
30 | FileKit.saveUploadedFile(req, "/tmp/upload");
31 | Message res = new Message();
32 |
33 | res.setStatus(200);
34 | res.setHeader("content-type", "text/html; charset=utf8");
35 | res.setBody("Uploaded Success
");
36 |
37 | return res;
38 | }
39 |
40 | @RequestMapping(path="/abc")
41 | public Object json() {
42 | Map value = new HashMap<>();
43 | value.put("key", System.currentTimeMillis());
44 | return value;
45 | }
46 |
47 | @RequestMapping(path="/favicon.ico", docEnabled=false)
48 | public Message favicon() {
49 | return fileKit.loadResource("static/favicon.ico");
50 | }
51 |
52 | @SuppressWarnings("resource")
53 | public static void main(String[] args) throws Exception {
54 |
55 | RpcProcessor p = new RpcProcessor();
56 | StaticResource resource = new StaticResource();
57 | resource.setBasePath("\\tmp");
58 |
59 | p.mount("", RpcServerDirectHttp.class);
60 | p.mount("static", resource);
61 |
62 | RpcServer server = new RpcServer(p);
63 | server.setPort(8080);
64 | server.start();
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/src/test/java/io/zbus/rpc/RpcServerDynamicMethod.java:
--------------------------------------------------------------------------------
1 | package io.zbus.rpc;
2 |
3 | import java.util.Arrays;
4 | import java.util.Map;
5 |
6 |
7 | public class RpcServerDynamicMethod {
8 |
9 | @SuppressWarnings("resource")
10 | public static void main(String[] args) throws Exception {
11 | GenericService service = new GenericService();
12 |
13 | //抽象的服务调用,增加一个具体的方法
14 | RpcMethod spec = new RpcMethod();
15 | spec.method = "func1";
16 | spec.paramTypes = Arrays.asList(String.class.getName(), Integer.class.getName());
17 | spec.paramNames = Arrays.asList("name", "age");
18 | spec.returnType = Map.class.getName();
19 |
20 | RpcProcessor p = new RpcProcessor();
21 | p.mount(spec, service);
22 |
23 |
24 | RpcServer server = new RpcServer(p);
25 | server.setPort(8080);
26 | server.start();
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/test/java/io/zbus/rpc/RpcServerMQ.java:
--------------------------------------------------------------------------------
1 | package io.zbus.rpc;
2 |
3 | import io.zbus.rpc.biz.InterfaceExampleImpl;
4 |
5 | public class RpcServerMQ {
6 |
7 | @SuppressWarnings("resource")
8 | public static void main(String[] args) throws Exception {
9 |
10 | RpcProcessor p = new RpcProcessor();
11 | p.setUrlPrefix("/test");
12 | p.mount("/example", InterfaceExampleImpl.class);
13 |
14 |
15 | RpcServer server = new RpcServer();
16 | //connect to zbus
17 | server.setProcessor(p);
18 | server.setMqServerAddress("localhost:15555");
19 | server.setMq("MyRpc2"); //MQ entry, RPC client incognito
20 | //MQ authentication, no need to configure if use HTTP direct RPC
21 | //server.setAuthEnabled(true);
22 | //server.setApiKey("2ba912a8-4a8d-49d2-1a22-198fd285cb06");
23 | //server.setSecretKey("461277322-943d-4b2f-b9b6-3f860d746ffd");
24 |
25 | server.start();
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/test/java/io/zbus/rpc/RpcServerMQInproc.java:
--------------------------------------------------------------------------------
1 | package io.zbus.rpc;
2 |
3 | import io.zbus.mq.MqServer;
4 | import io.zbus.mq.MqServerConfig;
5 | import io.zbus.rpc.biz.InterfaceExampleImpl;
6 |
7 | public class RpcServerMQInproc {
8 |
9 | @SuppressWarnings("resource")
10 | public static void main(String[] args) throws Exception {
11 |
12 | RpcProcessor p = new RpcProcessor();
13 | p.setUrlPrefix("/");
14 | p.mount("/example", InterfaceExampleImpl.class);
15 |
16 |
17 | //Serve RPC via MQ Server InProc
18 | MqServerConfig config = new MqServerConfig("0.0.0.0", 15555);
19 | config.setVerbose(false);
20 | MqServer mqServer = new MqServer(config);
21 |
22 | RpcServer server = new RpcServer(p);
23 | server.setMqServer(mqServer); //InProc MqServer
24 | server.setMq("MyRpc"); //Choose MQ to group Service physically, RPC incognito
25 |
26 | //MQ authentication, no need to configure if use HTTP direct RPC
27 | //server.setAuthEnabled(true);
28 | //server.setApiKey("2ba912a8-4a8d-49d2-1a22-198fd285cb06");
29 | //server.setSecretKey("461277322-943d-4b2f-b9b6-3f860d746ffd");
30 |
31 | server.start();
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/test/java/io/zbus/rpc/RpcServerSpring.java:
--------------------------------------------------------------------------------
1 | package io.zbus.rpc;
2 |
3 | import org.springframework.context.support.ClassPathXmlApplicationContext;
4 |
5 | public class RpcServerSpring {
6 |
7 | @SuppressWarnings("resource")
8 | public static void main(String[] args) throws Exception {
9 | new ClassPathXmlApplicationContext("rpc/context.xml");
10 | }
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/src/test/java/io/zbus/rpc/TestCases.java:
--------------------------------------------------------------------------------
1 | package io.zbus.rpc;
2 |
3 | import io.zbus.rpc.biz.InterfaceExample;
4 | import io.zbus.transport.Message;
5 |
6 | public class TestCases {
7 |
8 | public static void doTest(RpcClient rpc, String urlPrefix) throws Exception {
9 | //1) 原始的方法调用中的数据格式
10 | Message req = new Message();
11 | req.setUrl(urlPrefix+"/plus");
12 | req.setBody(new Object[] {1,2}); //body as parameter array
13 |
14 | Message res = rpc.invoke(req); //同步调用
15 | System.out.println(res);
16 |
17 | //2)纯异步API
18 | rpc.invoke(req, resp -> { //异步调用
19 | System.out.println(resp);
20 | });
21 |
22 | //3) 动态代理
23 | InterfaceExample example = rpc.createProxy(urlPrefix, InterfaceExample.class);
24 | int c = example.plus(1, 2);
25 | System.out.println(c);
26 |
27 |
28 | //4) 参数同时基于URL的调用格式
29 | req = new Message();
30 | req.setUrl(urlPrefix + "/plus/1/2");
31 | res = rpc.invoke(req);
32 | System.out.println("urlbased: " + res);
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/test/java/io/zbus/rpc/WebsocketClientExample.java:
--------------------------------------------------------------------------------
1 | package io.zbus.rpc;
2 |
3 | import java.util.concurrent.atomic.AtomicInteger;
4 |
5 | import io.zbus.transport.Message;
6 | import io.zbus.transport.http.WebsocketClient;
7 |
8 | public class WebsocketClientExample {
9 |
10 | @SuppressWarnings("resource")
11 | public static void main(String[] args) throws Exception {
12 | WebsocketClient rpc = new WebsocketClient("localhost:8080");
13 |
14 | AtomicInteger count = new AtomicInteger(0);
15 | for (int i = 0; i < 100000; i++) {
16 | Message req = new Message();
17 | req.setHeader("method", "getOrder");
18 | req.setHeader("module", "example");
19 |
20 |
21 | rpc.invoke(req, res->{
22 | int c = count.getAndIncrement();
23 | if(c % 10000 == 0) {
24 | System.out.println(c + ": " + res);
25 | }
26 | });
27 | }
28 | //rpc.close();
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/test/java/io/zbus/rpc/biz/DbExample.java:
--------------------------------------------------------------------------------
1 | package io.zbus.rpc.biz;
2 |
3 | import java.util.List;
4 |
5 | import org.apache.ibatis.session.SqlSession;
6 | import org.springframework.beans.factory.annotation.Autowired;
7 |
8 |
9 | public class DbExample {
10 |
11 | @Autowired
12 | SqlSession sqlSession;
13 |
14 | public List test(){
15 | return sqlSession.selectList("io.zbus.rpc.biz.db.test");
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/test/java/io/zbus/rpc/biz/DbInterface.java:
--------------------------------------------------------------------------------
1 | package io.zbus.rpc.biz;
2 |
3 | import java.util.List;
4 | import java.util.Map;
5 |
6 | import org.apache.ibatis.annotations.Param;
7 | import org.apache.ibatis.annotations.Select;
8 |
9 |
10 | public interface DbInterface {
11 | @Select("SELECT * FROM user WHERE User=#{userId}")
12 | Map getUser(@Param("userId") String userId);
13 |
14 | @Select("SELECT * FROM proc WHERE name = #{name}")
15 | Map getProc(@Param("name") String name);
16 |
17 | @Select("SELECT * FROM help_category")
18 | List