GithubHelp home page GithubHelp logo

anyrpc's People

Contributors

eikeverdenhalven avatar faaxm avatar sgieseking 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

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

anyrpc's Issues

To Use With Javascript Server/Client on JSON TCP Protocol

Hi,
AnyRpc work fine server/client on c++. But when I use it with another Server/Client on Javascript+Node on JsonHttp is still working fine. But I used with JsonTcp no data received on server.
My Javascript code (Server and Client) work fine together on jsontcp mode also, like the AnyRpc examples. But to mix or cross it that only work on JsonHttp.
The Javascript client for example is very simple like:
var client = jayson.client.tcp({port: 9000 })
client.request('add', [3.0, 5.0], function(err,response)){... throw ....}

Any idea ?

Thanks

TCP Connection via Messagepack contains multiple packets

TCPResendMultiPing_Cut.txt

We're using your anyrpc project to communicate to embedded devices. Assuring the devices are stilll alive we're sending a heartbeat to the device and wait for an answer. This occurs after waiting for 10ms (usually about around a second). Since we're having troubles with connection issues I recorded the TCP connection via tcpdump on linux and attached a filtered dump file.

In detail, we're sending the string ping to the device and are waiting for the string pong. This usually works, but sometimes the initial initiation of the connection is included in the actual payload. Sometimes this is messed up with multiple pings.

No.     Time           Source                Destination           Protocol Length Info
  52626 2327.495919    172.17.17.1           172.17.17.103         TCP      79     [TCP Retransmission] 52899 → 9000 [PSH, ACK] Seq=1298 Ack=23 Win=65536 Len=25

Frame 52626: 79 bytes on wire (632 bits), 79 bytes captured (632 bits)
Ethernet II, Src: FujitsuT_be:a8:d5 (90:1b:0e:be:a8:d5), Dst: Atmel_1f:ac:ca (fc:c2:3d:1f:ac:ca)
Internet Protocol Version 4, Src: 172.17.17.1, Dst: 172.17.17.103
Transmission Control Protocol, Src Port: 52899, Dst Port: 9000, Seq: 1298, Ack: 23, Len: 25
    Source Port: 52899
    Destination Port: 9000
    [Stream index: 1]
    [TCP Segment Len: 25]
    Sequence number: 1298    (relative sequence number)
    [Next sequence number: 1323    (relative sequence number)]
    Acknowledgment number: 23    (relative ack number)
    0101 .... = Header Length: 20 bytes (5)
    Flags: 0x018 (PSH, ACK)
    Window size value: 256
    [Calculated window size: 65536]
    [Window size scaling factor: 256]
    Checksum: 0xdce8 [unverified]
    [Checksum Status: Unverified]
    Urgent pointer: 0
    [SEQ/ACK analysis]
        [iRTT: 0.000329000 seconds]
        [Bytes in flight: 25]
        [Bytes sent since last PSH flag: 25]
        [TCP Analysis Flags]
            [Expert Info (Note/Sequence): This frame is a (suspected) retransmission]
            [The RTO for this segment was: 0.311942000 seconds]
            [RTO based on delta from frame: 52590]
    [Timestamps]
    TCP payload (25 bytes)
    Retransmitted TCP segment data (25 bytes)

0000  fc c2 3d 1f ac ca 90 1b 0e be a8 d5 08 00 45 00   ..=...........E.
0010  00 41 59 ea 40 00 80 06 26 42 ac 11 11 01 ac 11   .AY.@...&B......
0020  11 67 ce a3 23 28 ad 39 f5 a8 80 f9 35 23 50 18   .g..#(.9....5#P.
0030  01 00 dc e8 00 00 32 31 3a 93 02 a4 70 69 6e 67   ......21:...ping
0040  81 a1 23 82 a3 72 70 63 01 a3 63 6e 74 30 2c      ..#..rpc..cnt0,

[...]
No.     Time           Source                Destination           Protocol Length Info
  63651 2637.298319    172.17.17.1           172.17.17.103         TCP      101    [TCP Retransmission] 53000 → 9000 [PSH, ACK] Seq=3026 Ack=23 Win=65536 Len=47
0000  fc c2 3d 1f ac ca 90 1b 0e be a8 d5 08 00 45 00   ..=...........E.
0010  00 57 0c e2 40 00 80 06 73 34 ac 11 11 01 ac 11   [email protected]......
0020  11 67 cf 08 23 28 a0 b1 90 9b c5 c0 6b eb 50 18   .g..#(......k.P.
0030  01 00 49 8d 00 00 93 02 a4 70 69 6e 67 81 a1 23   ..I......ping..#
0040  82 a3 72 70 63 01 a3 63 6e 74 75 2c 32 31 3a 93   ..rpc..cntu,21:.
0050  02 a4 70 69 6e 67 81 a1 23 82 a3 72 70 63 01 a3   ..ping..#..rpc..
0060  63 6e 74 76 2c                                    cntv,

[...]
No.     Time           Source                Destination           Protocol Length Info
  72268 2724.402597    172.17.17.1           172.17.17.103         TCP      105    [TCP Retransmission] 53020 → 9000 [PSH, ACK] Seq=25610 Ack=23 Win=65536 Len=51
0000  fc c2 3d 1f ac ca 90 1b 0e be a8 d5 08 00 45 00   ..=...........E.
0010  00 5b 68 69 40 00 80 06 17 a9 ac 11 11 01 ac 11   .[hi@...........
0020  11 67 cf 1c 23 28 12 38 3e a8 27 93 71 f2 50 18   .g..#(.8>.'.q.P.
0030  01 00 a6 eb 00 00 93 02 a4 70 69 6e 67 81 a1 23   .........ping..#
0040  82 a3 72 70 63 01 a3 63 6e 74 cd 03 bf 2c 32 33   ..rpc..cnt...,23
0050  3a 93 02 a4 70 69 6e 67 81 a1 23 82 a3 72 70 63   :...ping..#..rpc
0060  01 a3 63 6e 74 cd 03 c0 2c                        ..cnt...,

Do you see any chance this might be caused in the anyrpc project? It looks like someone is not sending, but filling the send-buffer multiple times.

FAILED Compilation

hi,
I try to build your lib again. But now the compilation failed. Maybe after your last merge (24/01/2017). why you did not use a Branch or Tag to keep the old version code and the new with the modifications.

std::condition_variable condVarDelayedRemove_;
^
/data/IPC_TESTS/anyrpc/src/method.cpp: In member function ‘bool anyrpc::MethodManager::RemoveMethod(const string&, bool)’:
/data/IPC_TESTS/anyrpc/src/method.cpp:114:17: error: ‘condVarDelayedRemove_’ was not declared in this scope
condVarDelayedRemove_.wait(lock);
^
/data/IPC_TESTS/anyrpc/src/method.cpp: In member function ‘void anyrpc::MethodManager::ExecuteMethod_FollowUpOperations(anyrpc::Method*)’:
/data/IPC_TESTS/anyrpc/src/method.cpp:167:9: error: ‘condVarDelayedRemove_’ was not declared in this scope
condVarDelayedRemove_.notify_all(); // notify waiting calls of remove method (if any)
^
make[2]: *** [src/CMakeFiles/anyrpc.dir/method.cpp.o] Error 1
make[1]: *** [src/CMakeFiles/anyrpc.dir/all] Error 2
make: *** [all] Error 2

Thread safety of MethodManager

Hi,
I've run into a threading issue with the method manager, which was hard to find but can easily be forced to occur. First I'll give a short description how to reproduce the error, afterwards I'll explain and give my thoughts.

Reproduction

  1. Use the exampleServer and exampleClient from anyrpc examples. I used the single threaded JsonTcpServer, but the error probably occurs for all threaded servers.
  2. In method.cpp extend the ExecuteMethod like this:
    [...]
    if (it == methods_.end())
        return false;
    std::cout << "MethodManager paused..." << std::endl;
    std::this_thread::sleep_for(std::chrono::seconds(15));
    std::cout << "MethodManager going on." << std::endl;
    it->second->Execute(params,result);
    [...]
  1. In exampleServer.cpp change the line this_thread::sleep_for( chrono::seconds(timeout) ); to the following lines:
    this_thread::sleep_for( chrono::seconds(10) );
    std::cout << "Remove subtract now..." << std::endl;
    methodManager->RemoveMethod("add");
    std::cout << "Server changes finished." << std::endl;
    this_thread::sleep_for(chrono::seconds(30));
    std::cout << "Server shutting down..." << std::endl;
  1. Start the server and immediatly afterwards the client. The client will get plenty of timeouts, but this doesn't matter. On the server you'll get at "map/set iterator not dereferencable" error (at least for VS2015).

Explanation and Thoughts
Inside the server's worker thread incoming rpc-commands from client are directed to the ExecuteMethod function. However this access is not protected by any mutex, so nothing prevents the main thread (or any other thread) from accessing MethodManager. By adding the sleep in ExecuteMethod, I'm just "increasing" the possibility of a thread-change at this point.

If at this point the RemoveMethod function is called from main thread, the issue is obvious. The iterator is invalidated (and besides we do not have the corresponding function that should be executed anymore).

Note, that this issue does occur for any MethodManager function, because they all use iterators which might be invalidated. However (if I see this correctly) the invalidation does only occur for RemoveMethod. In AddMethod this issue does not occur, because a map is used and map-iterators aren't invalidated on insertion (unlike e.g. vectors). Still you could think of other problems, like adding multiple methods at the same time, listing and adding at the same time, ...

In general I would propose the usage of a mutex, which prevents from multiple access to any of the member functions, but I wanted to hear your oppinion first. The following problems might occur:

  • I'm not sure if a mutex might collide with any server type. Would there be a problem, if the ExecuteMethod-function was mutexed (e.g. because it is called multiple times in parallel)? If so, one could maybe use the std::shared_mutex (C++17)...
  • The call of member-functions would not be possible from within any other member-function. E.g. it would not be possible inside a rpc-command to ask for a list of all available commands. One could use a std::recursive_mutex (C++11) to allow this, but recursive mutexes are a controversial topic...

Any comments on these topics?

PS: I'm aware that the RemoveMethod function was added by one of my pull requests, but without it one would reactivate the problem of deleted references (discribed in #24).

Messagepack: Response parse error. Parsing was terminated.

I've checked out the current master and compiled on Win7 with VS2015. In the exampleServer.cpp I've changed the Add function:

void Add(Value& params, Value& result)
{
    result.SetMap();
    result["value"] = 0;
    result["text"] = "";
    std::cout << result << std::endl;
}

Now calling from command line with

start anyrpc\build\bin\Debug\exampleServer.exe jsontcptp 9000 10
start anyrpc\build\bin\Debug\exampleClient.exe jsontcp 127.0.0.1 9000

on client side I get as expected the result
success: 1, add: {"value":0,"text":""}

Using

start anyrpc\build\bin\Debug\exampleServer.exe messagepacktcptp 9000 10
start anyrpc\build\bin\Debug\exampleClient.exe messagepacktcp 127.0.0.1 9000

instead, I get a parse error:
unbenannt

The bug is probably related to using 0 as a value, but I'm not sure why.

Growing server buffer if using notifications

Hi,
I'm using the Client::Notify() functionality to send some strings to my Json-Tcp-server (I'm using a threadpool, but the behaviour is the same for single thread). On the server these strings are just printed to std::cout. Doing this I could observe the following behaviour: Sometimes not all messages are printed, but just the first x messages. When sending more messages later, first the missing messages are printed and the new ones are missing... This goes on and the amount of missing messages grows, but this growth is not constant.

Running in the debugger, I could track down the issue: In class Connectionon the server, the member variable buffer_ contains all the missing messages, so it's not a problem of the tcp-connection. If I understand the purpose of the code correctly, the problem is in function Connection::Process(). For notifications one never gets the state WRITE_RESPONSE so newMessage will be false even if other messages are in buffer.

I'm now using the hotfix

// When operating a thread pool, the main thread might need to continue
// to write a long response to the socket after the connection is returned
if (connectionState_ == WRITE_RESPONSE)
{
    if (!WriteResponse())
    {
        connectionState_ = CLOSE_CONNECTION;
        break;
    }
}

// Check if additional messages should be processed
newMessage = (connectionState_ == READ_HEADER) && (bufferLength_ > 1);

but I'm not totally sure if this is the correct fix. After all I had to use bufferLength_ >1 instead of >0 because otherwise one would have a infinite loop (in debugger bufferLength_ is 1 if no messages are left in the buffer, why so?). However this loop would also appear for Call(), but I'm really not sure why...

Warnings caused by type conversion

Hello,
I'm using the AnyRPC under Win7 with Visual Studio 2015. The target application shall be compiled for 32bit and 64bit. During compilation some warnings of this kind occur:
warning C4267: 'var' : conversion from 'size_t' to 'type', possible loss of data

Under 32bit it's only 'size_t' to 'char' having problems, and the position in code can easily be handled with a simple static_cast. However, under 64bit it's also 'size_t' to 'int', 'size_t' to 'uint32_t' and others. Most of the calls refer to arguments passed between different string functions.

Example:

    //! Copy the string as either a short string or with allocated memory.
    void CopyString(const char* s) { CopyString(s, strlen(s)); }
    //! Copy the string as either a short string or with allocated memory.
    void CopyString(const char* s, int length);

strlen(s) returns a size_t, while CopyString takes an int.
Does the anyrpc library fully support 64 bit or might I run into problems later on? Any hints / comments on how to solve this warning in a most appropriate way?

Method::Execute with const parameters

Hi @sgieseking,
thanks again for your support in my recent issues. This issue is more of a question and not really a problem:

When dealing with the Method-class

//! A MethodFunction is created with a function pointer that is call by the Execute method.
class MethodFunction : public Method
{
public:
    MethodFunction(Function* function, std::string const& name, std::string const& help, bool deleteOnRemove=true) :
        Method(name, help, deleteOnRemove), function_(function) {}
    virtual void Execute(Value& params, Value& result) { if (function_) function_(params, result); }
private:
    Function *function_;
};

I was wondering, if there would be any problem with making the "params" input of the Execute method constant:
virtual void Execute(const Value& params, Value& result)
If I see it correctly, params should never be changed by Execute, so this would lead to a more readable function body and self explaining code. It would require more changes to const in other functions (e.g. MethodManager::ListMethods), but I don't see any counter-argument.
After all, you have the better understanding of your class, so maybe you could tell me if I missed any point against this.

Thanks
Jan

Possible memory leak

Hi, I'm not quite sure about this problem and the best way to solve it, that's why I have created an issue instead of a pull-request.
Similar to the exampleServer, I might create a method like this:

class Multiply : public Method
{
public:
    Multiply() : Method("multiply", "Multiply two numbers",true) {};
    virtual void Execute(Value& params, Value& result) { // something}
};

Having set deleteOnRemove to "true", the deletion of the object shall be handled by AnyRpc.
Now suppose having a correct working server, I use it like this:

[...]
server->GetMethodManager()->AddMethod( new Multiply );
[...]
server->GetMethodManager()->AddMethod( new Multiply );
[...]

By this we would create a memory leak, wouldn't we?
Looking at

void MethodManager::AddMethod(Method* method)
{
    MethodMap::const_iterator it = methods_.find(method->Name());
    if (it == methods_.end())
        // not found so add new method
        methods_[method->Name()] = method;
}

the second call would not go into the if branch, which leads to pointer beeing lost without destroying the memory.
Of course the example does not make much sense, but I'm thinking about bigger projects. Between the two AddMethod calls might be a lot of stuff, they might even be called from different source files. It even has not to be the same class which is added, if I see it correctly only the "name" of the method is relevant.

I see the following solution:

void MethodManager::AddMethod(Method* method)
{
    MethodMap::const_iterator it = methods_.find(method->Name());
    if (it == methods_.end())
    {
        // not found so add new method
        methods_[method->Name()] = method;
    }
    else
    {
       // some error-message???
       if method->DeleteOnRemove()
            delete method;
    }
}

I'm not sure if this is the best solution or if it handles all possible cases. One might also think about usage of unique_ptr. Any thoughts on this problem?

Crash when receiving raw unicode data

I'm using anyrpc as a c++ RPC server and xmlrcp as a python client.

When I send a unicode string using xmlrcp, the string is sent with the UTF8 bytes (for exemple "ā" is sent as 0xC4 0x81 (which is -60, -127 in char).

Maybe this is an error from xmlrcp not to convert the UTF8 bytes to escaped xml characters like expected by anyrpc (&#C4&#81 I guess?), but anyway the software shall not crash when receiving this data.

The error is in Reader::IsWhiteSpace, it uses std::isspace which does not support negative signed char, see the official documentation: https://en.cppreference.com/w/cpp/string/byte/isspace

Paser error when receive `<params />`

XmlRpc.net will send <params /> when there is no parameters.
But AnyRPC can't parse it and return parse error.

For example:

<!-- Request -->
<?xml version="1.0"?>
<methodCall>
  <methodName>
    MethodName
  </methodName>
  <params/>
</methodCall>
<!-- Response -->
<?xml version="1.0" encoding="utf-8"?>
    <methodResponse>
        <fault>
            <value>
                <struct>
                    <member>
                        <name>
                            faultCode
                            </name>
                        <value>
                            <i4>
                                -32700
                                </i4>
                            </value>
                        </member>
                    <member>
                        <name>
                            faultString
                            </name>
                        <value>
                            Parse error
                            </value>
                        </member>
                    </struct>
                </value>
            </fault>
        </methodResponse>

Missing WSACleanup for Windows sockets

Hi again,
I just noticed, that you call WSAStartup in Socket() constructor if compiling for WIN32 (socket.cpp). However you never call WSACleanup, which should be done according to Microsoft:

An application must call the WSACleanup function for every successful time the WSAStartup function is called. This means, for example, that if an application calls WSAStartup three times, it must call WSACleanup three times. [source]

Do I miss something or is this a bug?

If I understand the Microsoft documentation correctly, you could just call WSAStartup in every constructor (not guarded by the wsInit) and similarly the WSACleanup in Destructor and everything would be fine.

Greatings
Jan

Maximum length of string for MsgPack is 127?!

Hi,
on my messagepack TCP-server I've added the method

class Print : public anyrpc::Method
{
public:
    Print() : Method("print", "Print given information.", true) {};
    virtual void Execute(anyrpc::Value& params, anyrpc::Value& result)
    {
        if (params.IsString())
        {
            std::string sTemp(params.GetString());
            std::cout << sTemp;
        }
        result = true;
    }
};

On my client I'm calling

std::string ten("123456789_");
std::string fifty(ten+ten+ten+ten+ten);
std::string temp(fifty+fifty+ten+ten+"12345678");
anyrpc::Value param(temp), result;
myClient->Notify("print",param, result);

When receiving this message on the server, I get the errors
unbenannt

I changed the length of the string and for me all strings of length <=127 are working. So it seems, that (2^7)-1 is the maximum lenth of a transmitted string. Is this on purpose or a bug?
Looking into the msgpack specification ( https://github.com/msgpack/msgpack/blob/master/spec.md#str-format-family ) I would expect that a maximum length of (2^32)-1 is supported. Or, if only str 8 is implemented at least (2^8)-1...

Using a JSON server and client instead, the same code works fine even with strings of length 1000 and more.

Bas64 with padding decoding fails when there is a new line character before the next tag

I'm using anyrpc as a c++ RPC server and xmlrcp as a python client.

xmlrpc send a pretty xml with a newline character before/after each tag.
But if the base64 string is padded (ends with = or ==) anyrpc always expects the next tag to be just after the end of the base64 string.
See Base64Decode method:

// verify termination character
return (is.Peek() == termChar);

Thread naming

Hi,
while developing multi-thread applications naming of threads (e.g. for debugging) has proven to be quite useful. In the following I'd like to propose some additions to your library. Use them if you like them, feel free to simply close this issue if you think otherwise...

Header threadName.h would be:

#ifndef THREAD_NAME_H_
#define THREAD_NAME_H_

#include <thread>

namespace misc
{
	/// name current thread
	void SetThreadName(const std::string& threadName);

	/// name thread identified by thread-handle
	void SetThreadName(std::thread& thread, const std::string& threadName);
}

#endif /* THREAD_NAME_H_ */

Source threadName.cpp would be the following, where the windows part is mainly based on this MSDN example (it appears "dirty", but I didn't find any cleaner solution):

#include "anyrpc/threadName.h"

#ifdef _WIN32 /* WINDOWS */

	#include <windows.h>  
	const DWORD MS_VC_EXCEPTION = 0x406D1388;

	#pragma pack(push,8)  
	typedef struct tagTHREADNAME_INFO
	{
		DWORD dwType;		// Must be 0x1000.  
		LPCSTR szName;		// Pointer to name (in user addr space).  
		DWORD dwThreadID;	// Thread ID (-1=caller thread).  
		DWORD dwFlags;		// Reserved for future use, must be zero.  
	} THREADNAME_INFO;
	#pragma pack(pop)

	void SetThreadName(DWORD dwThreadID, const char* threadName) {
		THREADNAME_INFO info;
		info.dwType = 0x1000;
		info.szName = threadName;
		info.dwThreadID = dwThreadID;
		info.dwFlags = 0;
	#pragma warning(push)  
	#pragma warning(disable: 6320 6322)  
		__try
		{
			RaiseException(MS_VC_EXCEPTION, 0, sizeof(info) / sizeof(ULONG_PTR), (ULONG_PTR*)&info);
		}
		__except (EXCEPTION_EXECUTE_HANDLER)
		{
		}
	#pragma warning(pop)  
	}

	namespace misc
	{
		void SetThreadName(const std::string& threadName)
		{
			::SetThreadName(GetCurrentThreadId(), threadName.c_str());
		}

		void SetThreadName(std::thread& thread, const std::string& threadName)
		{
			DWORD threadId = ::GetThreadId(static_cast<HANDLE>(thread.native_handle()));
			::SetThreadName(threadId, threadName.c_str());
		}
	}

#else /* LINUX */

	#include <sys/prctl.h>

	namespace misc
	{
		void SetThreadName(const std::string& threadName)
		{
			::prctl(PR_SET_NAME, threadName.c_str(), 0, 0, 0);
		}

		void SetThreadName(std::thread& thread, const std::string& threadName)
		{
			auto handle = thread.native_handle();
			::pthread_setname_np(handle, threadName.c_str());
		}
	}

#endif

Obviously this is not for MacOS yet...

Using the above header and source one could for example add this line to StartThread() in server.cpp:

misc::SetThreadName(thread_, "AnyRpcServer");

Adding such a line to all thread creations allows an easy recognition of different threads in a multi-thread-environment and also thread-name-dependent breakpoints (the latter at least in VS).

Growing file descriptor while running.

Hi,
I'm launching the exampleServer and exampleClient provided with this project and compiled with gcc under RHEL 7.0 by these command line calls:
build/bin/exampleServer jsontcp 9000 9000
buid/bin/exampleClient
If I run the client program for 100 times, the server response correctly. However, the file descriptor occupied by the exampleServer is keep growing, which can launch following command line:
ll /proc/$(pidof exampleServer)/fd
So If I want to open another file such a plain text file by rpc call, I may fail to open the file since the file descriptor is all occupied after many rpc call.
I wonder when the server will close the file descriptor ( socket fd ).
How can I solve this problem?

INADDR_LOOPBACK?

Have you guys considered adding an option to use INADDR_LOOPBACK instead of INADDR_ANY in Socket::Bind()? The latter binds to 0.0.0.0 which triggers firewalls, while the loopback option binds to the local address without additional firewall attention.

I'm using this library as a part of Spix project, which is UI automation library and all the network communication is done locally on the host, so those firewall's notifications are quite annoying. It would be really nice to have a "local only" option somewhere in AnyRPC please :)

Thank you.

Warning on disconnection of client

Hi,
I'm launching the exampleServer and exampleClient provided with this project and compiled with VisualStudio 2015 under Win7 64bit by these command line calls:

start anyrpc\build\bin\Debug\exampleServer.exe jsontcp 9000 100
start anyrpc\build\bin\Debug\exampleClient.exe jsontcp 127.0.0.1 9000

At the moment the client finishes its job, the server displays the following warning:
logmessage
In my own project, I noticed that this warning always occurs, if a Jsontcp-client calls the close() function. It's probably not even related to the target system and compiler, because it also happens on linux with gcc.

Are you able to reproduce this warning?

select() hangs in multithread application with activated timeouts

We're using the tcp-messagepack implementation of anyrpc with enabled threading.

Upon system shutdown we're closing down the connections and sometimes it happens that select() hangs up. This can be identified using the remote debugger for ARM. We're using a timeout of 100 ms.

Furthermore, using the variable _threadRunning as of type bool is not threadsafe and should be implemented as std::atomic.

A possible workaroung might be to look at signals for the usage with select().
http://man7.org/linux/man-pages/man2/select_tut.2.html

Has anyone considered this solution?

Unbind TCP-server?

Is there any way to "unbind" a anyrpc::server for TCP without destroying it?

Background: I've a server with some attached methods. Now I would like to stop the server, so it does not listen on any port for a while. Afterwards I would like to bind it again, depending on other information to the same or another port.
Is this possible? If yes, how do I do it?
Of course one could destroy the old and initialize a totally new server, but then all attached methods have to be bound again. I'd like to avoid this.

What I've tried:
I've called StopThread(), Exit(), Shutdown() on the server but still a call of BindAndListen() leads to:
"Could not bind to spedified port: -1".
I've tried to track the error further down, but the usage of sockets in general and in this library in particular remains kind of unclear to me. After all I do not really know when to use StopThread(), Exit() and Shutdown() and in which order. Any hint on that?

Thanks again for your great library. I see, that my problem might be a little special, but I hope that you can still give some information or point me in the right direction.

Additional function template for Value

What do you think about an additional function template for value.h?

//! Add member with string and any type known by value-constructor
    template<typename T>
    Value& Add2Map(const std::string& str, T& value) { Value tempValue(value); return AddMember(str.c_str(), str.length(), tempValue); }

Supposed the corresponding variables myString, myInt, myBool exist, instead of calls like

anyrpc::Value param(anyrpc::ValueType::MapType)
anyrpc::Value newMember;
newMember = anyrpc::Value( myString );
param.AddMember("print",newMember);
newMember = anyrpc::Value( myInt );
param.AddMember("number",newMember);
newMember = anyrpc::Value( myBool );
param.AddMember("boolean",newMember);

one could use

anyrpc::Value param(anyrpc::ValueType::MapType)
param.Add2Map("print",myString);
param.Add2Map("number",myInt );
param.Add2Map("boolean",myBool );

with the above function template. This occurs quite often for me.

Or is there any better way?

Crash on exit of examples with log4cplus

Hello @sgieseking,

I have successfully compiled the anyrpc examples with log4cplus on Windows with Visual Studio 2015.
The examples are running fine and the logging is working.
But the application crashes on exit.
I found an issue on the log4cplus project page having the same error. However I was not able to use this information to eliminate the crash.
Simply adding log4cplus::Initializer initializer; to the top of the main of exampleServer does not fix the error.
Can you give me a few pointers how the error can be corrected?

Thank you in advance for your time and help.

Greetings
Jan

Problems using log4cplus & anyrpc with unicode

Hi,

if I figured it correctly, anyrpc-logging is not working with unicode enabled.

Log4cplus itself supports unicode, for example I was building (on Win7 64bit, VS2015) with

cmake -DBUILD_SHARED_LIBS:BOOL=TRUE -DWITH_UNIT_TESTS=OFF -DLOG4CPLUS_BUILD_TESTING=OFF -DUNICODE=ON -DLOG4CPLUS_BUILD_LOGGINGSERVER=OFF -DLOG4CPLUS_SINGLE_THREADED=ON

However setting up anyrpc via

cmake -DBUILD_EXAMPLES=OFF -DBUILD_WITH_LOG4CPLUS=ON -DBUILD_WITH_WCHAR=ON -DBUILD_WITH_THREADING=ON -DUNICODE=ON -DLOG4CPLUS_LIBRARY_RELEASE=....\log4cplus\build\src\Release\log4cplusU.lib -DLOG4CPLUS_LIBRARY_DEBUG=....\log4cplus\build\src\Debug\log4cplusUD.lib

leads to a project file, that can't be compiled (note that I provided the correct libs from log4cplus, however you might need to manually add the UNICODE preprocessor define to anyrpc project).

When compiling the anyrpc-project one gets multiple errors like

binary operator '<<': no operator found which takes a right-hand operand of type 'std::string' (or there is no acceptable conversion)

or

'TimeLogger::TimeLogger(const TimeLogger &)' : cannot convert argument n from 'const char [1]' to 'log4cplus::tstring &'.

These errors are caused by calling log4cplus-macros, which obviously expect wchar (or corresponding strings) when compiled with UNICODE-preprocessor define. However the calls by anyrpc are done with simple chars, often fixed strings like "this is an example".

One solution for this problem would be, to use something like TCHAR and _T("my example") (these two only exist in Visual Studio as far as I know), but one would need to change all the logs accordingly.

For myself I found another "solution": In fact I don't really want unicode-logging, but I need the unicode-define enabled in my main project, because it is working with QT and QT needs unicode. So I just compile the dlls for anyrpc & log4cplus without UNICODE-preprocessor defined. In order to include correct headers in my main project, I changed the following lines in logger.h:

# ifdef UNICODE
# undef UNICODE
# define UNICODE_DISABLED_BECAUSE_ANYRPC_LOGGING_WITH_UNICODE_NOT_SUPPORTED
# endif
# include <log4cplus/log4cplus.h>
# define InitializeLogger() \

log4cplus::Initializer initializer; \
log4cplus::PropertyConfigurator config(LOG4CPLUS_TEXT("log4cplus.properties")); \
config.configure();

# ifdef UNICODE_DISABLED_BECAUSE_ANYRPC_LOGGING_WITH_UNICODE_NOT_SUPPORTED
# undef UNICODE_DISABLED_BECAUSE_ANYRPC_LOGGING_WITH_UNICODE_NOT_SUPPORTED
# define UNICODE
# endif

Obviously this is neither the cleanest nor a general solution, but this way UNICODE is defined everywhere (where QT needs it) except for the anyrpc / log4cplus part.

Any comments on this topic? Maybe I missed a point or there is a better way to get anyrpc running with unicode?

Problem with long Bas64 String in xmlrpc on embedded device

I send a long Base64 String in a xmlrpc from an anyrpc Server. The Server is on an embedded device (armv7l 32 bit processor.).

In my Python xmlrpc Client I get the following error message: xml.parsers.expat.ExpatError: no element found: line 2, column 25948

I try to use curl, but I get : curl: (18) transfer closed with 21434 bytes remaining to read

On Stack Overflow the mention it could be the `Content-Length. So I try to bring up the ContentLength in the Code. But the error peers.

Does anyone have an idea to solve this problem?

I see #48 there is a similar Problem with base64 and xmlrpc, but I think this is not the same problem.

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.