Search…

Socket.IO với Cocos2d-x

27/09/20206 min read
Hướng dẫn cách tạo game mulitiplay với Cocos2d-x thông qua Socket.IO.

Bài viết này sẽ hướng dẫn cách làm thế nào để có thể tạo 1 game mulitiplay với Cocos2d-x thông qua Socket.IO.

  • Network trong Cocos2d-x 3.x.x: Socket.IO.
  • Network trong Cocos2d-x 3.x.x: WebSockets.
  • Network trong Cocos2d-x 3.x.x: HTTPClient.

Bài viết sẽ giới thiệu về 1 ví dụ sử dụng Socket.IO trong Cocos2d-x, cung cấp kiến thức giúp có thể tạo game mulitiplay đơn giản, cũng như hỗ trợ bước đầu làm được 1 game online.

Socket.IO là gì?

Socket.IO là 1 thư viện JavaScript và cũng là 1 loại WebSocket API. 

Sự khác biệt rõ ràng nhất giữa Socket.IO và WebSockets:

  • Socket.IO cho phép send/emit messages bằng cách xác định bằng 1 tên event.
  • Trong trường hợp của Socket.IO: 1 message từ Server sẽ đến tất cả các Client đang kết nối. Với WebSockets: Nếu muốn điều tương tự như Socket.IO cần phải tạo 1 mảng của tất cả các kết nối và lặp qua nó để gửi message đến tất cả các client.

Cấu hình

Download và cài đặt Node.js.

Khởi tạo project. Ở đây 1 folder có tên là STDIO_SERVER.

Để cấu hình và chạy server. Có thể sử dụng command line hoặc GitSCM.

  • Vào folder STDIO_SERVER và sử dụng command line.
  • Sử dụng GitSCM: Right mouse click và selected Git Bash Here. Có thể download Git tại http://git-scm.com.

Tiếp theo cài đặt Socket.IO. Có 2 cách để cài đặt:

  • Sử dụng file manifest.
  • Không sử dụng file manifest (command line/GIT).

Sử dụng file manifest

Sử dụng file manifest package.json (file cấu hình) có nội dung như sau:

{
    "name":"stdio_server",
    "version":"0.0.1",
    "private":"true",
    "dependencies":
{      "socket.io":"0.9.16",     } }

Ở đây trong phần dependencies khai báo version Socket.IO .

Ngoài ra, nếu sử dụng nhiều modules khác của Socket.IO như express,... có thể khai báo vào trong phần dependencies này.

Sau đó, sử dụng command line/GIT và lệnh sau để cấu hình cho server.

npm install

Không sử dụng file manifest

Ngoài cách sử dụng file manifest package.json. Có thể sử dụng command line hoặc GIT để cài đặt SocketIO với lệnh như sau:

npm install socket.io@0.9.16

Với 0.9.16 chính là version của socket IO. Tương tự như với các modules khác như express.

Kết quả

Sau khi cấu hình xong. Trong folder STDIO_SERVER sẽ có 1 folder node_modules.

Capture

Hiện thực Server

Sau khi cấu hình xong, tạo 1 file JavaScript tên là STDIO_SERVER.js để có thể chạy Server của mình trong folder STDIO_SERVER

var http = require('http'),
socketIO = require('socket.io'),

port = 8888,
ip = '127.0.0.1',

server = http.createServer().listen(port, ip, function(){
    console.log('Socket.IO server started at %s:%s!', ip, port);
}),

io = socketIO.listen(server);

var run = function(socket){
    console.log('connect....');

    socket.emit('hello', 'Hello from Socket.IO');
    socket.send('Hello from SocketIO');
  
    socket.on('echotest', function (data) {
        console.log(data);
    })

    socket.on('message', function(msg){
        console.log('Received: ' + msg);
    });

    socket.disconnect('disconnect', function() {
        console.log('Client disconnect');
    });
}

io.sockets.on('connection', run);

Phân tích:

Trong Node.js, function requires() được dùng để import 1 module.

  • Dòng 1-11: đoạn code này sẽ:
    • Khởi động 1 Server HTTP.
    • Khai báo 1 biến server sử dụng module http có sẵn trong Node.js.
    • Lắng nghe ở port 8888 (Chờ đợi một yêu cầu kết nối từ Client).
    • Chú ý: lúc này Server vẫn chưa làm gì cả kể có khi có 1 yêu cầu kết nối từ Client.
  • Dòng 13: khi 1 Client kết nối với Server thì sẽ function này sẽ được gọi. Lúc này Server đã bắt đầu làm việc. Socket.IO cung cấp 3 event chính là connect, messagedisconnect ở cả 2 phía server và client. 1 client kết nối tới Server bằng function connect().
  • Dòng 16: gửi dữ liệu tới cho tất cả các Client đang kết nối. Với tên event là hello và nội dung là Hello from Socket.IO.
  • Dòng 17: gửi dữ liệu tới cho tất cả các Client đang kết nối. Với tên event mặc định là message và nội dung là Hello from STDIO.
  • Dòng 19-21: nhận dữ liệu từ Client với tên event là echotest và nội dung là biến data.
  • Dòng 23-25: nhận dữ liệu từ Client với tên event là message và nội dung là biến msg. Cũng tương tự như ở Server, ở phía Client cũng có function send() nhằm gửi dữ liệu với tên event mặc định là message.
  • Dòng 27-29: khi Server đóng kết nối với Client.

Run Server

Để chạy Server, dùng sử dụng lệnh sau:

node STDIO_SERVER.js
Capture(1)

Client

Khởi tạo dự án. Trong bài viết này, ví dụ sẽ thực hiện trên các file có sẵn sau khi khởi tạo project:

  • HelloWordScene.h
  • HelloWordScene.cpp

HelloWordScene.h

#ifndef __HELLOWORLD_SCENE_H__
#define __HELLOWORLD_SCENE_H__

#include "cocos2d.h"
#include "ui/cocosGUI.h"

#include <network/SocketIO.h>

using namespace cocos2d::network;
using namespace cocos2d::ui;

class HelloWorld : public cocos2d::Layer, public SocketIO::SIODelegate
{
public:
    static cocos2d::Scene* createScene();

    virtual bool init();
    
    // a selector callback
    void menuCloseCallback(cocos2d::Ref* pSender);
    
    // implement the "static create()" method manually

    // socket.io even\vent listener
    void onReceiveEvent(SIOClient* client, const std::string& data);
    // SIODelegate
    virtual void onConnect(SIOClient* client);
    virtual void onMessage(SIOClient* client, const std::string& data);
    virtual void onClose(SIOClient* client);
    virtual void onError(SIOClient* client, const std::string& data);

    CREATE_FUNC(HelloWorld);

protected:
private:
    int index;
    SIOClient* _client;
    TextField* editBox;
};

#endif // __HELLOWORLD_SCENE_H__

Phân tích:

  • Dòng 7: thêm thư viện để có thể làm việc với Socket.IO.
  • Dòng 12: khởi tạo class HelloWord có kế thừa public với SocketIO::SIODelegate
  • Dòng 25-30: các phương thức làm việc với Server. 
  • Dòng 37: khai báo 1 SocketClient. Dùng biến này để connect, gửi data và nhận data với Server.

HelloWorldScene.cpp

#include "HelloWorldScene.h"

USING_NS_CC;

Scene* HelloWorld::createScene()
{
    // 'scene' is an autorelease object
    auto scene = Scene::create();
    
    // 'layer' is an autorelease object
    auto layer = HelloWorld::create();

    // add layer as a child to scene
    scene->addChild(layer);

    // return the scene
    return scene;
}

// on "init" you need to initialize your instance
bool HelloWorld::init()
{
    //////////////////////////////
    // 1. super init first
    if ( !Layer::init() )
    {
        return false;
    }
    
    Size visibleSize = Director::getInstance()->getVisibleSize();
    Vec2 origin = Director::getInstance()->getVisibleOrigin();

	// connect to server
	_client = SocketIO::connect("http://127.0.0.1:8888", *this);
	_client->on("message", CC_CALLBACK_2(HelloWorld::onReceiveEvent, this));
	_client->emit("message", "het hon chua");
    
    return true;
}

void HelloWorld::onConnect(SIOClient* client) {
	// SocketIO::connect success
}
void HelloWorld::onMessage(SIOClient* client, const std::string& data) {
	// SocketIO::send receive
}
void HelloWorld::onClose(SIOClient* client) {
	// SocketIO::disconnect success
}
void HelloWorld::onError(SIOClient* client, const std::string& data) {
	// SocketIO::failed
}

void HelloWorld::onReceiveEvent(SIOClient* client, const std::string& data) {
	auto lbl = Label::createWithTTF(data, "fonts/Marker Felt.ttf", 24);
	lbl->setPosition(Vec2(100, 100));
	this->addChild(lbl);
};

Phân tích:

  • Dòng 34: thiết lập tới địa chỉ "http://127.0.0.1:8888". Gửi thông điệp tới Server 1 connect.
  • Dòng 35: thiết lập nhận dữ liệu từ Server. Khi Server gửi dữ liệu tới Client. Lúc này Client sẽ thực thi phương thức HelloWord::onReceiveEvent();
  • Dòng 36: để gửi 1 tin nhắn tới Server. Cũng như Server sử dụng function emit(eventName, args).

Build/Run

Sau khi chạy server cũng như client (project game) có kết quả sau:

Capture(2)
asd

Demo 

Bài viết đã hoàn thành việc giới thiệu cách tạo 1 Server đơn giản cũng như các function cơ bản về thao tác cơ bản giữa Client (Cocos2d-x) với Server.

Từ đây, có thể sử dụng Socket.IO trong các project game mulitiplayer.

Có thể download toàn bộ mã nguồn trong bài viết này ở phía dưới đây:

SERVER_ZIP

CLIENT_ZIP

IO Stream

IO Stream Co., Ltd

30 Trinh Dinh Thao, Hoa Thanh ward, Tan Phu district, Ho Chi Minh city, Vietnam
+84 28 22 00 11 12
developer@iostream.co

383/1 Quang Trung, ward 10, Go Vap district, Ho Chi Minh city
Business license number: 0311563559 issued by the Department of Planning and Investment of Ho Chi Minh City on February 23, 2012

©IO Stream, 2013 - 2024