Giter Site home page Giter Site logo

hprose / hprose-java Goto Github PK

View Code? Open in Web Editor NEW
550.0 104.0 187.0 58.32 MB

Hprose is a cross-language RPC. This project is Hprose 2.0 for Java

License: MIT License

Java 99.20% HTML 0.06% Batchfile 0.64% Shell 0.10%
rpc rpc-library rpc-framework rpc-server rpc-service rpc-client api cross-platform cross-language java

hprose-java's Introduction

Hprose

Hprose for Java

Join the chat at https://gitter.im/hprose/hprose-java Maven Central GitHub release License

Hprose is a High Performance Remote Object Service Engine.

It is a modern, lightweight, cross-language, cross-platform, object-oriented, high performance, remote dynamic communication middleware. It is not only easy to use, but powerful. You just need a little time to learn, then you can use it to easily construct cross language cross platform distributed application system.

Hprose supports many programming languages, for example:

  • AAuto Quicker
  • ActionScript
  • ASP
  • C++
  • Dart
  • Delphi/Free Pascal
  • dotNET(C#, Visual Basic...)
  • Golang
  • Java
  • JavaScript
  • Node.js
  • Objective-C
  • Perl
  • PHP
  • Python
  • Ruby
  • ...

Through Hprose, You can conveniently and efficiently intercommunicate between those programming languages.

This project is the implementation of Hprose for Java.

Hprose 2.0 for Java Documents: https://github.com/hprose/hprose-java/wiki

hprose-java's People

Contributors

andot avatar dependabot[bot] avatar dsonet avatar gitter-badger avatar linkerlin avatar warmonipa avatar xiaoyur347 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

hprose-java's Issues

服务器使用PHP语言开发的,然后我用Java语言请求,明明有响应数据,但是一直抛异常

不知道为什么这里一直是REJECTED状态
switch (promise.getState()) {
case FULFILLED: return result;
case REJECTED: throw new ExecutionException(promise.getReason());
}

异常如下:
Exception in thread "main" java.util.concurrent.ExecutionException: hprose.common.HproseException: Wrong Response:
Rm3{s6"status"i200;s3"ret"0s4"data"a{}}Aa1{m3{s4"name"s2"小兰"s5"ep_id"1s6"status"1}}z{"status":200,"ret":0,"data":[]}
at hprose.util.concurrent.PromiseFuture.get(PromiseFuture.java:82)
at hprose.client.HproseClient.invoke(HproseClient.java:740)
at hprose.client.HproseClient.invoke(HproseClient.java:704)
at test.Test.test2(Test.java:60)
at test.Test.main(Test.java:47)
Caused by: hprose.common.HproseException: Wrong Response:
Rm3{s6"status"i200;s3"ret"0s4"data"a{}}Aa1{m3{s4"name"s2"小兰"s5"ep_id"1s6"status"1}}z{"status":200,"ret":0,"data":[]}
at hprose.client.HproseClient.decode(HproseClient.java:478)
at hprose.client.HproseClient.access$300(HproseClient.java:65)
at hprose.client.HproseClient$7.call(HproseClient.java:551)
at hprose.client.HproseClient$7.call(HproseClient.java:547)
at hprose.util.concurrent.Promise.call(Promise.java:739)
at hprose.util.concurrent.Promise.resolve(Promise.java:753)
at hprose.util.concurrent.Promise._resolve(Promise.java:775)
at hprose.util.concurrent.Promise.resolve(Promise.java:789)
at hprose.util.concurrent.Promise.call(Promise.java:739)
at hprose.util.concurrent.Promise.resolve(Promise.java:753)
at hprose.util.concurrent.Promise._resolve(Promise.java:775)
at hprose.util.concurrent.Promise.resolve(Promise.java:789)
at hprose.util.concurrent.Promise.call(Promise.java:739)
at hprose.util.concurrent.Promise.resolve(Promise.java:753)
at hprose.util.concurrent.Promise._resolve(Promise.java:775)
at hprose.util.concurrent.Promise.resolve(Promise.java:789)
at hprose.util.concurrent.Promise.call(Promise.java:739)
at hprose.util.concurrent.Promise.resolve(Promise.java:753)
at hprose.util.concurrent.Promise._resolve(Promise.java:775)
at hprose.util.concurrent.Promise.resolve(Promise.java:789)
at hprose.util.concurrent.Promise.call(Promise.java:739)
at hprose.util.concurrent.Promise.resolve(Promise.java:753)
at hprose.util.concurrent.Promise._resolve(Promise.java:775)
at hprose.util.concurrent.Promise.resolve(Promise.java:789)
at hprose.util.concurrent.Promise.resolve(Promise.java:756)
at hprose.util.concurrent.Promise._resolve(Promise.java:775)
at hprose.util.concurrent.Promise.resolve(Promise.java:789)
at hprose.client.HproseHttpClient$2.run(HproseHttpClient.java:321)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)

为什么要限定static方法必须用类调用

HproseMethods,Line167
((obj == null) == Modifier.isStatic(method.getModifiers()))
这里的判断,为什么要限定呢
而且这里添加方法的时候,如果没有找到,尽可能抛出异常或者有返回状态比较好,这个方法建议修改一下:

private boolean addMethod(String methodName, Object obj, Class<?> type, String aliasName, HproseResultMode mode, boolean simple) {
Method[] methods = type.getMethods();
for (Method method : methods) {
if (methodName.equals(method.getName()) &&
((obj != null) || Modifier.isStatic(method.getModifiers()))) {
addMethod(aliasName, new HproseMethod(method, obj, mode, simple));
return true;
}
}
return false;
}

java.lang.NoSuchMethodError: Can't find this method getUser

public class User implements Serializable {
	private static final long serialVersionUID = 2566816725396650300L;

	private long id;
	private String name;
	private int sex;
	private LocalDate birthday;
	private List<Integer> permissions;
	private int status;
	private LocalDateTime createTime;
	
	//getters and setters ...
}
public interface UserService {
	public boolean existUser(String email);
	public boolean createUser(User user);
	public User getUser(long id);
	public Page<User> listUser(int pageNo);
}
Exception in thread "main" java.lang.reflect.UndeclaredThrowableException
	at com.sun.proxy.$Proxy0.getUser(Unknown Source)
	at benchmark.rpc.Client.main(Client.java:84)
Caused by: java.util.concurrent.ExecutionException: hprose.common.HproseException: java.lang.NoSuchMethodError: Can't find this method getUser
	at hprose.util.concurrent.PromiseFuture.get(PromiseFuture.java:82)
	at hprose.client.HproseClient.invoke(HproseClient.java:731)
	at hprose.client.HproseClient.invoke(HproseClient.java:695)
	at hprose.client.HproseInvocationHandler.invoke(HproseInvocationHandler.java:165)
	... 2 more

Security

Hi !

I was wondering if there is a built in security while calling a method in hprose. I mean actually i guess the server just bind a port and accept every incoming communication including illegit ones.

idea中测试hprose tomcat 关闭时 hprose报错误信息

hprose-php 做服务端,hprose-java做客户端 结合 springmvc
idea里能正常启动tomcat,没有错误信息,并且可以访问到hprose-php服务端的数据。
但关闭tomcat时,提示如下:
严重 [main] org.apache.catalina.loader.WebappClassLoaderBase.checkThreadLocalMapForLeaks The web application [ROOT] created a ThreadLocal with key of type [hprose.io.ByteBufferStream$1] (value [hprose.io.ByteBufferStream$1@5f3a4b84]) and a value of type [hprose.io.ByteBufferStream.ByteBufferPool] (value [hprose.io.ByteBufferStream$ByteBufferPool@670b40af]) but failed to remove it when the web application was stopped. Threads are going to be renewed over time to try and avoid a probable memory leak.

信息 [Thread-11] org.apache.catalina.loader.WebappClassLoaderBase.checkStateForResourceLoading Illegal access: this web application instance has been stopped already. Could not load [java.util.concurrent.ScheduledExecutorService]. The following stack trace is thrown for debugging purposes as well as to attempt to terminate the thread which caused the illegal access.
java.lang.IllegalStateException: Illegal access: this web application instance has been stopped already. Could not load [java.util.concurrent.ScheduledExecutorService]. The following stack trace is thrown for debugging purposes as well as to attempt to terminate the thread which caused the illegal access.
at org.apache.catalina.loader.WebappClassLoaderBase.checkStateForResourceLoading(WebappClassLoaderBase.java:1383)
at org.apache.catalina.loader.WebappClassLoaderBase.checkStateForClassLoading(WebappClassLoaderBase.java:1371)
at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1224)
at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1186)
at hprose.util.concurrent.Promise$1.run(Promise.java:40)
at hprose.util.concurrent.Threads$2.run(Threads.java:98)
at hprose.util.concurrent.Threads$1.run(Threads.java:73)

Exception in thread "Thread-11"
是什么原因呢?

Could not find class 'java.time.LocalDate'

Error Detail:

Could not find class 'java.time.LocalDate', referenced from method hprose.io.unserialize.UnserializerFactory.

Test Environment:

Phone: MI 3
OS Version: Android 4.4.4

JSON format support?

Hi~
Great work!

When hprose-java's filter can add support for JSON convert? any plans?

Android: Could not find method java.util.concurrent.ConcurrentHashMap.keySet

08-05 15:38:02.711 21811-22026/com.cloudpos I/dalvikvm: Could not find method java.util.concurrent.ConcurrentHashMap.keySet, referenced from method hprose.client.HproseClient.unsubscribe
08-05 15:38:02.711 21811-22026/com.cloudpos W/dalvikvm: VFY: unable to resolve virtual method 44695: Ljava/util/concurrent/ConcurrentHashMap;.keySet ()Ljava/util/concurrent/ConcurrentHashMap$KeySetView;

get 乱码

获取方法列表时返回的是乱码
image

hprose-Java 远程调用性能不知道是快还是慢?

在ThinkPadW540 8Core超线程 32G内存机器上,测试hprose.tcphelloexam.TCPHelloServerh和对应的hprose.tcphelloexam.TCPHelloClient,最终测试结果与下基本类似:
C:\Java\jdk8\bin\java .....
START
136167
END

耗时基本在130秒左右

从代码TCPHelloClient中,可以看出是20个客户端线程,每个线程调用hello后台服务30万次,共计600万次

也就是hprose-java针对最简单的hellow字符串调用,在以上配置的机器上只能跑4.4万笔/秒

不知道这个性能是快还是慢?

Suggestion : continuous calls of StringBuilder.append

Hi,
    I have found some continuous calls about StringBuilder.append(..) in some files. For example, there are several continuous calls from line 61 to 76 in the file https://github.com/hprose/hprose-java/blob/master/example/MyApplication/app/src/main/java/org/hprose/myapplication/MainActivity.java

public void run() {
                            TextView text = (TextView)findViewById(R.id.textView);
                            StringBuilder sb = new StringBuilder();
                            for (int i = 0; i < users.length; i++) {
                                sb.append("name: ");
                                sb.append(users[i].name);
                                sb.append("\r\n");
                                sb.append("sex: ");
                                sb.append(users[i].sex);
                                sb.append("\r\n");
                                sb.append("birthday: ");
                                sb.append(users[i].birthday);
                                sb.append("\r\n");
                                sb.append("age: ");
                                sb.append(users[i].age);
                                sb.append("\r\n");
                                sb.append("married: ");
                                sb.append(users[i].married);
                                sb.append("\r\n");
                                sb.append("\r\n");
                            }
                            text.setText(sb.toString());
}

    If it was achieved like StringBuilder.append(..).append(..)append(..), it will promote its performance.

请教一个问题

首先支持一下Hprose, 使用起来很方便.
我在尝试用Hprose搭建一组服务器, 有一个问题不知如何解决
假设某个请求路径: client->Server B->Server A
若A发生异常, 则最终会反馈给client, 但client不知是A还是B发生了问题
且异常信息没有说明是哪个函数(或调用堆栈)产生了异常
最重要的, Server自己有日志系统, 但Hprose把异常直接反馈给调用方, 导致无法获知并记录日志
希望能有一个统一的异常回调, 能通知发生了异常(方便记录), 然后再反馈给调用方
网上资料太少, 论坛又太冷清, 所以来这里请教, 见谅

环境差异导致不能连接到服务器,如何排查

由于目前使用的是局域网,功能一切正常,但搬到阿里云的经典网络中以后使用客户端就无法连接到服务端订阅消息了,客户端连接阿里云hprose服务后没有任何反应,服务器相应的订阅日志也没有激发
排查过如下

  1. centos7防火墙已关闭
  2. 无论是服务器本地还是远程telnet服务器的ip port都可以通 说明端口一打开
  3. 阿里云安全组排查没有限制相应的端口,且采用的是禁用部分端口,放开其他端口的做法
  4. 局域网服务器和阿里云服务器代码相同 无论是连域名或者ip地址服务端都没有看到订阅的日志输出
    服务端代码如下
    image

image

客户端代码如下
image
与服务器的链接是建立了 但一直没有链接成功的日志输出
image

ByteBufferStream是否需要close?

ByteBufferStream究竟需不需要close?
ByteBufferStream怎么获取byte[]?是toArray()?还是 byteBufferStream.buff.array()?
还有能否给API加点注释吗?

java.io.EOFException 03-14 09:39:14.077: W/System.err(5935): at libcore.io.Streams.readAsciiLine(Streams.java:203)

我们在开发手机移动端的时候,在andriod4.0版本上,不断出现以下错误,困扰了我们很久:
java.io.EOFException
03-14 09:39:14.077: W/System.err(5935): at libcore.io.Streams.readAsciiLine(Streams.java:203)
03-14 09:39:14.077: W/System.err(5935): at libcore.net.http.HttpEngine.readResponseHeaders(HttpEngine.java:573)
03-14 09:39:14.077: W/System.err(5935): at libcore.net.http.HttpEngine.readResponse(HttpEngine.java:821)
03-14 09:39:14.077: W/System.err(5935): at libcore.net.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:283)
03-14 09:50:46.547: W/System.err(6476): at libcore.net.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:177)
03-14 09:50:46.547: W/System.err(6476): at libcore.net.http.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:271)
经过搜查,需要以下设置
if (Build.VERSION.SDK != null&& Build.VERSION.SDK_INT > 13) {
urlConnect.setRequestProperty("Connection", "close");
}
http://stackoverflow.com/questions/15411213/android-httpsurlconnection-eofexception
咱们hporse 的java客户端,可以通过HproseHttpClient.setHeader("Connection", "close")进行urlConnect属性指定,但是查看源代码发现,
对于“Connection”属性,设置不起作用。
我手工修改了源代码,设置了以上参数后,上面错误不再出现,希望新版本能支持!

服务器在NAT后,无法使用。

版本1.5.2 h_for_java8
运行包中带的TCPHello_的例子可以运行。

  1. 在本地,如果helloServer和helloClient中的ip任何一个不使用localhost,比如其中一个使用(本机ip)192.168..,另一个使用localhost。连接不成功。 同时使用192.168._.*是可以的。 server和client中的地址必须写成一模一样才能用吗?
    2.server 在远程服务器上,服务器是通过nat分配的公网ip,在服务器本机ping自己的公网ip是ping到的。
    所以server使用公网ip会出错。 如果写成它的内网ip,就会重复了第1个问题,客户端写的是公网ip,服务端是自己的内网ip。连接失败。

关于内存溢出的疑问

hprose-java的server,用的版本是2.0.38.服务在运行一段时间之后就会出现内存溢出的异常,服务器openfile过多,不知道是哪里配置的不对。

Exception in thread "Thread-11" java.lang.OutOfMemoryError: Direct buffer memory
	at java.nio.Bits.reserveMemory(Bits.java:695)
	at java.nio.DirectByteBuffer.<init>(DirectByteBuffer.java:123)
	at java.nio.ByteBuffer.allocateDirect(ByteBuffer.java:311)
	at hprose.io.ByteBufferStream$ByteBufferPool.allocate(ByteBufferStream.java:64)
	at hprose.io.ByteBufferStream$ByteBufferPool.access$200(ByteBufferStream.java:31)
	at hprose.io.ByteBufferStream.allocate(ByteBufferStream.java:107)
	at hprose.net.Connection.receive(Connection.java:138)
	at hprose.net.Reactor.dispatch(Reactor.java:100)
	at hprose.net.Reactor.run(Reactor.java:49)
Exception in thread "Thread-10" java.lang.OutOfMemoryError: Direct buffer memory
	at java.nio.Bits.reserveMemory(Bits.java:695)
	at java.nio.DirectByteBuffer.<init>(DirectByteBuffer.java:123)
	at java.nio.ByteBuffer.allocateDirect(ByteBuffer.java:311)
	at hprose.io.ByteBufferStream$ByteBufferPool.allocate(ByteBufferStream.java:64)
	at hprose.io.ByteBufferStream$ByteBufferPool.access$200(ByteBufferStream.java:31)
	at hprose.io.ByteBufferStream.allocate(ByteBufferStream.java:107)
	at hprose.net.Connection.receive(Connection.java:138)
	at hprose.net.Reactor.dispatch(Reactor.java:100)
	at hprose.net.Reactor.run(Reactor.java:49)
Exception in thread "Thread-12" java.lang.OutOfMemoryError: Direct buffer memory
	at java.nio.Bits.reserveMemory(Bits.java:695)
	at java.nio.DirectByteBuffer.<init>(DirectByteBuffer.java:123)
	at java.nio.ByteBuffer.allocateDirect(ByteBuffer.java:311)
	at hprose.io.ByteBufferStream$ByteBufferPool.allocate(ByteBufferStream.java:64)
	at hprose.io.ByteBufferStream$ByteBufferPool.access$200(ByteBufferStream.java:31)
	at hprose.io.ByteBufferStream.allocate(ByteBufferStream.java:107)
	at hprose.net.Connection.receive(Connection.java:138)
	at hprose.net.Reactor.dispatch(Reactor.java:100)
	at hprose.net.Reactor.run(Reactor.java:49)
Exception in thread "Thread-14" java.lang.OutOfMemoryError: Direct buffer memory

hprose java

android studio 开发的时候。使用hprose2.0里面的推送,jar包在哪里下载。有没有demo.

An illegal reflective access operation has occurred

WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by hprose.io.access.ConstructorAccessor (file:/home/jiangliuer/Documents/gradle_cache/caches/modules-2/files-2.1/org.hprose/hprose-java/2.0.38/f76814f7b7cb685786568faf9502e1e643112e27/hprose-java-2.0.38.jar) to method java.io.ObjectStreamClass.newInstance()
WARNING: Please consider reporting this to the maintainers of hprose.io.access.ConstructorAccessor
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release

Complex self defined Object serialize support.

Hi,andot. I encountered some serializer problem while using HPROSE for rpc, it will try to make the Object[] arguments serialized. but hprose seems to support the basic types of arguments but not for complexd (or with self-defined) arguments. I don't know how to register the specific serializer. here comes the arguments.

1.ITransferMsg

public interface ITransferMsg<T> extends java.io.Serializable {
    String getIdentifier();

    MetaData getMetaData();

    T getPayload();

    Class<?> getPayloadType();

    ITransferMsg<T> withMetaData(Map<String, Object> metaData);

    ITransferMsg<T> andMetaData(Map<String, Object> metaData);

    Map<String,Object> getMetaValue();
}

2.ITransferMsg implementation

public class GenericTransferMsg<T> implements ITransferMsg<T> {
    private static final long serialVersionUID = -2860606356253432506L;
    private final String identifier;
    private final MetaData metaData;
    private final Class<?> payloadType;
    private final T payload;

    // for kryo default constructor is needed
    public GenericTransferMsg() {
        identifier = null;
        metaData = MetaData.emptyInstance();
        payload = null;
        payloadType = Void.TYPE;
    }

    /**
     * Constructs a Message for the given 
     * <code>payload</code> using empty metadata.
     * 
     * @param payload The payload for the message
     */
    public GenericTransferMsg(T payload) {
        this(payload, MetaData.emptyValues());
    }

    /**
     * Constructs a Message for the given 
     * <code>payload</code> and <code>meta data</code>.
     * 
     * @param payload The payload for the message
     * @param metaData The meta data for the message
     */
    public GenericTransferMsg(T payload, Map<String, Object> metaData) {
        this(UUIDHelper.random().toString(), payload, metaData);
    }

    /**
     * @param payload
     * @param metData
     */
    public GenericTransferMsg(T payload, MetaData metData) {
        this(UUIDHelper.random().toString(), payload, metData);
    }

    /**
     * Constructor to reconstruct a Message using existing data.
     * 
     * @param identifier The identifier of the Message
     * @param payload The payload of the message
     * @param metaData The meta data of the message
     */
    public GenericTransferMsg(String identifier, T payload, Map<String, Object> metaData) {
        this(identifier, payload, MetaData.from(metaData));
    }

    /**
     * Constructor to reconstruct a Message using existing data.
     * 
     * @param identifier The identifier of the Message
     * @param payload The payload of the message
     * @param metaData The meta data of the message
     */
    public GenericTransferMsg(String identifier, T payload, MetaData metaData) {
        this.identifier = identifier;
        this.metaData = metaData;
        this.payload = payload;
        this.payloadType = payload.getClass();
    }

    protected GenericTransferMsg(GenericTransferMsg<T> original, Map<String, Object> metaData) {
        this(original, MetaData.from(metaData));
    }

    protected GenericTransferMsg(GenericTransferMsg<T> original, MetaData metaData) {
        this.identifier = original.getIdentifier();
        this.payload = original.getPayload();
        this.payloadType = payload.getClass();
        this.metaData = metaData;
    }

    @Override
    public String getIdentifier() {
        return identifier;
    }

    @Override
    public MetaData getMetaData() {
        return metaData;
    }

    @Override
    public T getPayload() {
        return payload;
    }

    @Override
    public Class<?> getPayloadType() {
        return payloadType;
    }

    @Override
    public GenericTransferMsg<T> withMetaData(Map<String, Object> newMetaData) {
        return this.metaData.getValues().equals(newMetaData) ? this : new GenericTransferMsg<T>(this, newMetaData);
    }

    @Override
    public GenericTransferMsg<T> andMetaData(Map<String, Object> additionalMetaData) {
        return additionalMetaData.isEmpty() ? this : new GenericTransferMsg<T>(this, this.metaData.mergedWith(additionalMetaData));
    }

    @Override
    public Map<String, Object> getMetaValue() {
        return this.metaData.getValues();
    }


}

3.GenericTransferMsg inheritance:

public class ChannelTransferMsg extends GenericTransferMsg<byte[]> {
    private static final long serialVersionUID = -2860594938222827822L;

    private ChannelTransferMsg() {
        super();
    }

    private ChannelTransferMsg(byte[] payload) {
        super(payload);
    }

    private ChannelTransferMsg(byte[] payload, Map<String, Object> metaData) {
        super(payload, metaData);
    }

    private ChannelTransferMsg(byte[] payload, MetaData metaData) {
        super(payload, metaData);
    }

    private ChannelTransferMsg(String identifier, byte[] payload, Map<String, Object> metaData) {
        super(identifier, payload, metaData);
    }

    private ChannelTransferMsg(String identifier, byte[] payload, MetaData metaData) {
        super(identifier, payload, metaData);
    }

    private ChannelTransferMsg(ChannelTransferMsg original, MetaData metaData) {
        super(original, metaData);
    }

    public ChannelTransferMsg mergeDataData(Map<String, Object> additionalMetaData) {
        return additionalMetaData.isEmpty() ? this : new ChannelTransferMsg(this, getMetaData().mergedWith(additionalMetaData));
    }

    public static ChannelTransferMsg createTransferMsg() {
        return new ChannelTransferMsg();
    }

    public static ChannelTransferMsg createTransferMsg(byte[] payload) {
        return new ChannelTransferMsg(payload);
    }

    public static ChannelTransferMsg createTransferMsg(byte[] payload, Map<String, Object> metaData) {
        return new ChannelTransferMsg(payload, metaData);
    }

    public static ChannelTransferMsg createTransferMsg(byte[] payload, MetaData metaData) {
        return new ChannelTransferMsg(payload, metaData);
    }

    public static ChannelTransferMsg createTransferMsg(String identifier, byte[] payload, Map<String, Object> metaData) {
        return new ChannelTransferMsg(identifier, payload, metaData);
    }

    public static ChannelTransferMsg createTransferMsg(String identifier, byte[] payload, MetaData metaData) {
        return new ChannelTransferMsg(identifier, payload, metaData);
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder(100);

        sb.append("Identifier{").append(getIdentifier())
          .append("},PayLoad{").append(new String(getPayload()))
          .append("},MetaData{").append(getMetaData().toString())
          .append("}");

        return sb.toString();
    }

}

4.MetaData around the msg:

public class ChannelTransferMsg extends GenericTransferMsg<byte[]> {
    private static final long serialVersionUID = -2860594938222827822L;

    private ChannelTransferMsg() {
        super();
    }

    private ChannelTransferMsg(byte[] payload) {
        super(payload);
    }

    private ChannelTransferMsg(byte[] payload, Map<String, Object> metaData) {
        super(payload, metaData);
    }

    private ChannelTransferMsg(byte[] payload, MetaData metaData) {
        super(payload, metaData);
    }

    private ChannelTransferMsg(String identifier, byte[] payload, Map<String, Object> metaData) {
        super(identifier, payload, metaData);
    }

    private ChannelTransferMsg(String identifier, byte[] payload, MetaData metaData) {
        super(identifier, payload, metaData);
    }

    private ChannelTransferMsg(ChannelTransferMsg original, MetaData metaData) {
        super(original, metaData);
    }

    public ChannelTransferMsg mergeDataData(Map<String, Object> additionalMetaData) {
        return additionalMetaData.isEmpty() ? this : new ChannelTransferMsg(this, getMetaData().mergedWith(additionalMetaData));
    }

    public static ChannelTransferMsg createTransferMsg() {
        return new ChannelTransferMsg();
    }

    public static ChannelTransferMsg createTransferMsg(byte[] payload) {
        return new ChannelTransferMsg(payload);
    }

    public static ChannelTransferMsg createTransferMsg(byte[] payload, Map<String, Object> metaData) {
        return new ChannelTransferMsg(payload, metaData);
    }

    public static ChannelTransferMsg createTransferMsg(byte[] payload, MetaData metaData) {
        return new ChannelTransferMsg(payload, metaData);
    }

    public static ChannelTransferMsg createTransferMsg(String identifier, byte[] payload, Map<String, Object> metaData) {
        return new ChannelTransferMsg(identifier, payload, metaData);
    }

    public static ChannelTransferMsg createTransferMsg(String identifier, byte[] payload, MetaData metaData) {
        return new ChannelTransferMsg(identifier, payload, metaData);
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder(100);

        sb.append("Identifier{").append(getIdentifier())
          .append("},PayLoad{").append(new String(getPayload()))
          .append("},MetaData{").append(getMetaData().toString())
          .append("}");

        return sb.toString();
    }

}

I want to make use of the transferMsg(like the channeTransferMsg), but it is not the standard one like simple object like user

Android客户端使用订阅,服务器端重启的情况,客户端无法自动重连服务器。

public final void onTimeout(Connection conn, TimeoutType type) {
if (TimeoutType.CONNECT_TIMEOUT == type) {
responses.remove(conn);
Request request;
while ((request = requests.poll()) != null) {
request.result.reject(new TimeoutException("connect timeout"));
}
}
else if (TimeoutType.IDLE_TIMEOUT != type) {
Map<Integer, Response> res = responses.get(conn);
if (res != null) {
Iterator<Map.Entry<Integer, Response>> it = res.entrySet().iterator();
while (it.hasNext()) {
Map.Entry<Integer, Response> entry = it.next();
it.remove();
Response response = entry.getValue();
response.timer.clear();
response.result.reject(new TimeoutException(type.toString()));
}
}
}
}
客户端在上面函数中进入死循环,出不来了。 while ((request = requests.poll()) != null) {
request.result.reject(new TimeoutException("connect timeout"));
}中

'void hprose.io.serialize.WriterRefer.addCount(int)' on a null object reference

07-02 13:21:19.934: W/System.err(29505): java.lang.NullPointerException: Attempt to invoke virtual method 'void hprose.io.serialize.WriterRefer.addCount(int)' on a null object reference
07-02 13:21:19.935: W/System.err(29505): at hprose.io.serialize.HproseWriter.writeClass(HproseWriter.java:482)
07-02 13:21:19.935: W/System.err(29505): at hprose.io.serialize.OtherTypeSerializer.write(OtherTypeSerializer.java:48)
07-02 13:21:19.935: W/System.err(29505): at hprose.io.serialize.OtherTypeSerializer.write(OtherTypeSerializer.java:62)
07-02 13:21:19.935: W/System.err(29505): at hprose.io.serialize.HproseWriter.serialize(HproseWriter.java:85)
07-02 13:21:19.935: W/System.err(29505): at hprose.io.serialize.ObjectArraySerializer.write(ObjectArraySerializer.java:41)
07-02 13:21:19.935: W/System.err(29505): at hprose.io.serialize.HproseWriter.writeArray(HproseWriter.java:387)
07-02 13:21:19.935: W/System.err(29505): at hprose.client.HproseClient.doOutput(HproseClient.java:553)
07-02 13:21:19.935: W/System.err(29505): at hprose.client.HproseClient.invoke(HproseClient.java:532)
07-02 13:21:19.935: W/System.err(29505): at hprose.client.HproseClient$1.run(HproseClient.java:297)
07-02 13:21:19.935: W/System.err(29505): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
07-02 13:21:19.935: W/System.err(29505): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
07-02 13:21:19.935: W/System.err(29505): at java.lang.Thread.run(Thread.java:818)

Add maven support

As a state-of-art RPC framework, the maven support is must be option.

hprose RPC protocol speed

Hi there

I made some test in order to benchmark hprose RPC protocol and i was very surprised to see that it is slower then making an http request.

The test i made is really simple i just wrote a hello world http method that answer "hello" to an http get and wrote a client that call it 100 times.

Then i wrote a hrpose server listening on TCP having a helloworld method and call it from an hprose client 100 times.

I monitoring the execution time of both protocol and HTTP protocol win all the time expect when the number of call is above 1000.

I was exepecting that a self made protocole was quicker then HTTP.

Did i made something wrong here ?

SkyWalking HProse plugin for auto instrument

Since SkyWalking became an Apache project, we are going to build a more wildly support ecosystem. So I want to know:

  • Does the HProse team want to provide the plugins for hprose-java released version? If yes, which versions do you prefer to support?

null pointer exception

Hi,

The following two methods may receive a uri with undefined scheme. Thus getScheme() may return null, which causes a null pointer exception. The similar problem may arise in hprose.client.HproseTcpClient. Although it is clearly stated in the wiki that only http and tcp are supported, it is better to add such null checks.

public static HproseClient hprose.client.HproseHttpClient.create(String uri, HproseMode mode) throws IOException, URISyntaxException {
        String scheme = (new URI(uri)).getScheme().toLowerCase();
        if (!scheme.equals("http") && !scheme.equals("https")) {
            throw new HproseException("This client doesn't support " + scheme + " scheme.");
        }
        return new HproseHttpClient(uri, mode);
}

public static HproseClient hprose.client.HproseHttpClient.create(String[] uris, HproseMode mode) throws IOException, URISyntaxException {
        for (int i = 0, n = uris.length; i < n; ++i) {
            String scheme = (new URI(uris[i])).getScheme().toLowerCase();
            if (!scheme.equals("http") && !scheme.equals("https")) {
                throw new HproseException("This client doesn't support " + scheme + " scheme.");
            }
        }
        return new HproseHttpClient(uris, mode);
    }

HproseTcpClient may miss the first request after connected

The step to reproduce:

  1. The server is in loopback mode or the server is in the same machine with the client.
  2. call IProtocol protocol = Client.useService("0.0.0.0:port").
  3. call protocol.func() only once to synchronize call to the server.
    Sometimes this call will fail.

Reason:
The client will wait HproseClient.timeout before it fails, and the default time is 5000ms or 5s.

Since it is the first call, size = 0, it will call ConnectorHolder.create() to connect to server.
When the server lives in the same machine with the client, maybe onConnected() is called before requests.offer(request);
And the connection becomes idle!
If we do rpc call again, it has the chance to communicate, but if we only communicate once, it may fail forever.

protected final void create(Request request) {
        if (size.get() < client.getMaxPoolSize()) {
            try {
                ConnectorHolder.create(client.uri, this, client.isKeepAlive(), client.isNoDelay());
            }
            catch (IOException ex) {
                request.result.reject(ex);
//                while ((request = requests.poll()) != null) {
//                    request.result.reject(ex);
//                }
                return;
            }
        }
        requests.offer(request);
    }
public final void onConnected(Connection conn) {
        Request request = requests.poll();
        if (request != null) {
            send(conn, request);
        }
        else { //come here
            synchronized (idleConnections) {
                if (!idleConnections.contains(conn)) {
                    idleConnections.offer(conn);
                }
            }
            recycle(conn);
        }
    }

The problem is idleConnections lock range is too small for onConnected().
And I suggest this:

public final void onConnected(Connection conn) {
    synchronized (idleConnections) {
        Request request = requests.poll();
        if (request != null) {
            send(conn, request);
        }
        else {
                if (!idleConnections.contains(conn)) {
                    idleConnections.offer(conn);
                }
            recycle(conn);
        }
    }
}

Since create() is only called by fetch(), and fetch() has a big lock for idleConnections. And we can share this lock to avoid the problem.

在安卓手机上,订阅有数量限制么?

1、服务端使用hprose-nodejs
2、安卓上使用hprose-java
在使用中发现,当订阅数超过3个时,会造成invoke调用返回变得缓慢
现在改成只使用两个订阅,用字段进行区分

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.