LIBUV has proven very mature through the practice and application of node. js, which was originally used for the project: Clsocket Https://github.com/DFHack/clsocket chose it primarily because it supported windows, Linux, Mac OSX (I guess), but the fatal disadvantage is only to support blocking TCP, which will lead to a problem, when connected to the game server, chat server when the game main interface will be directly blocked, and so on after the successful connection to return to normal. And the game was replaced before Luasocket, the main problem is to rely on the LUA loop to detect whether there are new data (timers), resulting in significant interface delay. Cocos2d-x 3.x version As a result of a significant increase in performance, it seems that this problem is not obvious, and we because of the project history is obvious, Lua and C + + is very dead, itself running up on one card.
Of course there are a lot of good C + + TCP network libraries, but most seem to write only to support Linux/unix, not to support windows at all. And our developers must first of all be developed under Windows, God Horse? With Mac, it's hard to get a 512G SSD for an imac, so don't dream. Do you own your own money or bring your own Mac notebook? No way! External USB is not allowed, do you want to use it? Go to an OA single application, the general developer's application is directly rejected, except for the main course (OK, I am more fortunate-"the main process")
Spit Groove to spit groove, live or work to drop. LIBUV in the actual use of some of the problems I found, if the connection socket when the background to actively disconnect, then the last message sent out of the background may not be received (probabilistic, the solution is to let the background send the message after a few seconds delay and then close the socket connection). When the iOS device is powered off, the socket is immediately disconnected, and the game needs to be automatically re-attached once it switches from the background to the foreground. And LIBUV because itself is implemented with pure C, its callback method is basically a static function, with C + + package words a little trouble, online also someone with c++11 package is better, unfortunately I use the NDK version is relatively low, support c++11 features have to give up, But other people's ideas can be borrowed from, feel very praise.
Take the client as an example, first understand the basic use of the next LIBUV, example from gist (all LIBUV functions start with uv_)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <uv.h>
#define LOG (x) printf ("%s\n", x);
uv_loop_t *loop;
voidOn_connect (uv_connect_t *req,intstatus);
voidOn_write_end (uv_write_t *req,intstatus);
uv_buf_t Alloc_buffer (uv_handle_t *handle, size_t suggested_size);
voidEcho_read (uv_stream_t *server, ssize_t nread, uv_buf_t buf);
//サーバからのレスポンスを says
voidEcho_read (uv_stream_t *server, ssize_t nread, uv_buf_t buf) {
if(Nread = =-1) {
fprintf (stderr,"Error Echo_read");
return;
}
//Results をbufから obtained 前転して開脚座り expression
printf"Result:%s\n", buf.base);
}
//Suggeseted_sizeで Watanabe された to insure
uv_buf_t Alloc_buffer (uv_handle_t *handle, size_t suggested_size) {
//Reading cups komagome みのためのバッファを, サジェストされたサイズで ensure
returnUv_buf_init ((Char*) malloc (suggested_size), suggested_size);
}
after//サーバへデータ, サーバからのレスポンスを reading cups komagome 飲む
voidOn_write_end (uv_write_t *req,intStatus) {
if(Status = =-1) {
fprintf (stderr,"Error On_write_end");
return;
}
//Books Earpick komagome みが わったら, すぐにreading cups komagome みを started
Uv_read_start (Req->handle, Alloc_buffer, Echo_read);
}
//サーバとの after Yobitsugi, サーバに letter
voidOn_connect (uv_connect_t *req,intStatus) {
if(Status = =-1) {
fprintf (stderr,"Error On_write_end");
return;
}
//Messenger メッセージを registration
Char*message ="Hello.txt";
intLen = strlen (message);
/**これだとセグフォ
* uv_buf_t buf[1];
* Buf[0].len = len;
* buf[0].base = message;
*/
//Messenger Sdts with のバッファ
CharBUFFER[100];
uv_buf_t buf = uv_buf_init (buffer,sizeof(buffer));
//Messenger データを download せる
Buf.len = Len;
buf.base = message;
//ハンドルを obtained
uv_stream_t* TCP = req->handle;
//Books Earpick Komagome cups with the structure of the body
uv_write_t Write_req;
intBuf_count = 1;
//Books Earpick Komagome cups
Uv_write (&write_req, TCP, &buf, Buf_count, on_write_end);
}
intMainvoid) {
//Loop generation
loop = Uv_default_loop ();
//Network i/oの Body Building
uv_tcp_t client;
//Loopへの registration
Uv_tcp_init (Loop, &client);
//アドレスの obtained
structsockaddr_in req_addr = uv_ip4_addr ("127.0.0.1", 7000);
//tcpコネクション body building
uv_connect_t Connect_req;
//Connect Yobitsugi
Uv_tcp_connect (&connect_req, &client, req_addr, On_connect);
//ループを Start
returnUv_run (loop);
}
LIBUV basic steps to use:
1. Generate a loop (Uv_default_loop () or uv_loop_t _loop)
2. Initialize a client,uv_tcp_init
3, connect the specified server, Uv_tcp_connect
4. Turn on message loop, Uv_run
Normally when used, we all need to start a new thread and execute uv_run in that thread to ensure that the currently called thread is not blocked (Uv_run is blocked and does not return immediately).
Use the key functions of the thread: uv_thread_create (Create Thread), Uv_async_init, uv_async_send (thread communication), the message is sent asynchronously, and in another thread multiple times (two or more) are called uv_async_ After the Send function it will only guarantee that the Uv_async_init callback function is called at least once
The uv_async_send is non-blocking and is also not thread-safe, and the access order should be guaranteed as much as possible with mutexes or read-write locks when accessing variables.
Our game server is a two-line, so the data returned to the client is the domain name + port, where you need to first convert the domain name to IP and then make Uv_tcp_connect connection.
Example code:
uv_getaddrinfo_t* Getaddrinfo_handle = (uv_getaddrinfo_t*) malloc (sizeof(uv_getaddrinfo_t));
this;
int r = uv_getaddrinfo (&loop_, Getaddrinfo_handle, &afterdnsresolved, m_strdomain.c_str (), NULL, NULL );
R returns 0 for normal, not 0 indicates an error message can be obtained by Uv_err_name (R), Uv_strerror (R)
Uvbook Example of Querydns:
intMain () {
loop = Uv_default_loop ();
structAddrinfo hints;
hints.ai_family = pf_inet;
Hints.ai_socktype = Sock_stream;
Hints.ai_protocol = ipproto_tcp;
hints.ai_flags = 0;
uv_getaddrinfo_t Resolver;
fprintf (stderr,"Irc.freenode.net is ... ");
intR = Uv_getaddrinfo (loop, &resolver, on_resolved,"Irc.freenode.net","6667", &hints);
if(r) {
fprintf (stderr,"Getaddrinfo call error%s\n", Uv_err_name (R));
return1;
}
returnUv_run (Loop, uv_run_default);
}
voidOn_resolved (uv_getaddrinfo_t *resolver,intStatusstructAddrinfo *res) {
if(Status < 0) {
fprintf (stderr,"Getaddrinfo callback error%s\n", Uv_err_name (status));
return;
}
CharADDR[17] = {' + '};
Uv_ip4_name ((structsockaddr_in*) res->ai_addr, addr, 16);
fprintf (stderr,"%s\n", addr);
uv_connect_t *connect_req = (uv_connect_t*) malloc (sizeof(uv_connect_t));
uv_tcp_t *socket = (uv_tcp_t*) malloc (sizeof(uv_tcp_t));
Uv_tcp_init (loop, socket);
Uv_tcp_connect (Connect_req, Socket, (Conststructsockaddr*) res->ai_addr, on_connect);
Uv_freeaddrinfo (RES);
}
LIBUV Engineering builds under Windows, using the officially recommended Gyp to generate vs solutions
1. Install and set up Python (version 2.6 or 2.7)
2, the source directory to create a new build directory, and then download Gyp to the directory
3, double-click the execution vcbuild.bat can
When referencing Libuv.lib in other projects, you need to add a few system lib to the VS additional dependency, or you will get an error
Libuv.lib
Advapi32.lib
Iphlpapi.lib
PSAPI.lib
Shell32.lib
Userenv.lib
Ws2_32.lib
Android under Compile LIBUV.A, I installed the virtual machine and then toss it up for a while and finally give up, refer to the Linux generated Mk himself complete with a full MK file
Local_path: =$(Call My-dir)
Include$(Clear_vars)
Local_module: = uv_static
Local_module_filename: = Libuv
#LOCAL_SRC_FILES: = PROJ.ANDROID/LIBUV.A
#LOCAL_EXPORT_CFLAGS: =-i$ (Local_path)/include
Local_src_files: = \
Src/fs-poll.b =
Src/inet.b =
Src/threadpool.b =
Src/uv-common.b =
Src/version.b =
Src/unix/async.b =
Src/unix/core.b =
Src/unix/dl.b =
Src/unix/fs.b =
Src/unix/getaddrinfo.b =
Src/unix/getnameinfo.b =
Src/unix/loop.b =
Src/unix/loop-watcher.b =
Src/unix/pipe.b =
Src/unix/poll.b =
Src/unix/process.b =
Src/unix/signal.b =
Src/unix/stream.b =
Src/unix/tcp.b =
Src/unix/thread.b =
Src/unix/timer.b =
Src/unix/tty.b =
Src/unix/udp.b =
Src/unix/proctitle.b =
Src/unix/linux-core.b =
Src/unix/linux-inotify.b =
Src/unix/linux-syscalls.b =
Src/unix/pthread-fixes.b =
Src/unix/android-ifaddrs.C
Local_c_includes: =$(Local_path)/include \
$(Local_path)/src \
$(Local_path)/src/unix
Local_export_c_includes: =$(Local_path)/include \
$(Local_path)/src \
$(Local_path)/src/unix
Local_cflags: = \
-wall \
-fvisibility=hidden \
-G \
--std=gnu89 \
-pedantic \
-wall \
-wextra \
-wno-unused-parameter \
-wstrict-aliasing \
-O3 \
-fstrict-aliasing \
-fomit-frame-pointer \
-fdata-sections \
-ffunction-sections
Include$(build_static_library)
In the jni/android.mk of the project, you only need to add
Local_whole_static_libraries + = Uv_static
$ (call IMPORT-MODULE,LIBUV)
Note Add the NDK's search path
When you need to use Uv.h in your project, modify the corresponding android.mk file,
Local_c_includes + = $ (local_path)/. /.. /libuv/include \
The directory itself is modified according to its own environment
If everything works, you'll see a successful compilation of files in the obj directory of the Eclipse project.
Under iOS, the default LIBUV only provides the compilation under the Mac, and modifies it to support iOS.
1. Download Libuv https://github.com/joyent/libuv/releases
2. Shell enters LIBUV
$mkdir-P Build
$git Clone Https://git.chromium.org/external/gyp.git Build/gyp
3. $./gyp_uv.py-f Xcode
Generate Xcode project Files Uv.xcodeproj
4. Open Xcode, modify architectures
XCode7, the first version of the latest SDK, the above is used in the older. If you refer to the project, add the LIBUV.A to the project, and then the framework search path and header search path are added to the path.
Here, all three platforms have been taken care of. I was introduced into the project, mainly referring to the
Libuv_tcp https://github.com/wqvbjhc/libuv_tcp
Also borrowed from the
Libsourcey Https://github.com/sourcey/libsourcey
UVPP HTTPS://GITHUB.COM/LARROY/UVPP
My own collection of a LIBUV for LUA project, feel pretty good too. Luv Https://github.com/luvit/luv is interested in being able to tinker with the same as node. js
There are two links attached to Uvbook:
English version (latest V1.3.0) https://nikhilm.github.io/uvbook/introduction.html
Chinese version (V0.9.8) http://www.nowx.org/uvbook/index.html
The use of LIBUV in Cocos2d-x