The use of LIBUV in Cocos2d-x

Source: Internet
Author: User

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

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.