All Articles

cocos2d-x(v3.2)でWebSocketやってみた

cocos2d-xでWebSocketしてみた

最近cocos2d-xを触り始めて、リアルタイムだしWebSocketで色々やりたいなーって調べた備忘録。 cocos2d-x v3.x系のエントリがまだ少ないので、ちょっとずつ勉強したことをメモしていこうかと思います。

cocos2d::network::WebSocketを使えばいい

のですが、メインなSceneのクラスにWebSokcet::Delegateを実装するのはなんか微妙な感じがした(個人的に)ので、 別クラスでDelegateを実装しておいて、Sceneからはnewして接続してイベントコールバックで処理するのがスマートなのかもって思いました。 JSっぽく使えるし、わかりやすい。

なお、まだC++は勉強を始めたばかりなのでツッコミは歓迎です。難しい。。。

//
//  SWebSocket.h
//
//  Created by Yoshiaki Sugimoto on 2014/08/04.
//
//
 
#ifndef __SWebSocket_H__
#define __SWebSocket_H__
 
#include "cocos2d.h"
#include "network/WebSocket.h"
 
class SWebSocket: public cocos2d::network::WebSocket::Delegate
{
private:
    std::string _url;
    cocos2d::network::WebSocket* _websocket;
public:
    std::function<void(std::string message)> onMessageReceived;
    std::function<void()> onConnectionClosed;
    std::function<void(const cocos2d::network::websocket::errorcode &error)> onErrorOccurred;
    std::function<void()> onConnectionOpened;
    
    SWebSocket(std::string url);
    
    void connect();
    
    static SWebSocket* create(std::string url);
    
    virtual void onOpen(cocos2d::network::WebSocket* ws);
    virtual void onMessage(cocos2d::network::WebSocket* ws, const cocos2d::network::WebSocket::Data& data);
    virtual void onError(cocos2d::network::WebSocket* ws, const cocos2d::network::WebSocket::ErrorCode& error);
    virtual void onClose(cocos2d::network::WebSocket* ws);
    
    void close();
    void send(std::string message);
    
    ~SWebSocket();
};
 
#endif /* defined(__SWebSocket_H__) */
</void()></void(const></void()></void(std::string>```

<p>ヘッダファイルの方はフルの名前空間で書くみたいに教わったんだけどこれでいいのかな…</p>

// // SWebSocket.cpp // // Created by Yoshiaki Sugimoto on 2014/08/04. // //

include “SWebSocket.h”

USINGNSCC; using namespace cocos2d::network;

SWebSocket* SWebSocket::create(std::string url) { SWebSocket* ws = new SWebSocket(url);
return ws; }

SWebSocket::SWebSocket(std::string url) { _url = url; };

void SWebSocket::connect() { websocket = new WebSocket(); _websocket->init(*this, _url.cstr()); }

void SWebSocket::close() { if (_websocket->getReadyState() == WebSocket::State::OPEN) { _websocket->close(); } }

SWebSocket::~SWebSocket() { _websocket->close(); }

void SWebSocket::send(std::string message) { if (_websocket->getReadyState() == WebSocket::State::OPEN) { _websocket->send(message); } }

void SWebSocket::onOpen(WebSocket* ws) { CCLOG(“WebSocket connection opened: %s”, url.cstr()); if ( onConnectionOpened ) { onConnectionOpened(); } }

void SWebSocket::onMessage(WebSocket* ws, const WebSocket::Data &data) { if ( onMessageReceived ) { onMessageReceived(data.bytes); }
}

void SWebSocket::onError(WebSocket* ws, const WebSocket::ErrorCode& error) { if ( onErrorOccurred ) { onErrorOccurred(error); } }

void SWebSocket::onClose(WebSocket* ws) { if ( onConnectionClosed ) { onConnectionClosed(); } }

<p>WebSocketのサーバ側はnodeで作った。</p>

var ws = require(‘websocket.io’); var server = ws.listen(8126);

server.on(‘connection’, function(socket) { console.log(‘Connection started’); console.log(socket.constructor);

    socket.on('message', function(data) {
            console.log('Message received:' + data);

            server.clients.forEach(function(client) {
                    client && client.send(data);
            });
    });

});

<p>コードは<a href="https://gist.github.com/ysugimoto/9bd511f417e96dc70c79">Gist</a>にも上げています。</p>

<h2>使い方という程でもないけど</h2>

<p>プロジェクトに追加して、インスタンス生成して、connect()ってするだけ。</p>

include “SWebSocket.h”

// インスタンス生成 SWebSocket *ws = new SWebSocket(“ws://websokcet-url”);

// イベント設定 ws->onConnectionOpened = { // do something }; ws->onMessageReceived = { // do something }; ws->onConnectionClosed = { // do something };

// 接続開始 ws->connect();

// 接続終了 ws->close();

<p>まだcocos2d-xの内部の仕組みがよく分かってないけど、コールバック的な振る舞いはstd::functionをcall出来るような感じにすればいいっぽい(EventListenerのonTouchBeganがそうやってたので参考にした)。
これでブラウザで接続中のWebSocketとcocos2dのアプリ間でメッセージの送受信ができた。</p>

<h2>まとめ</h2>
<p>v2系からガラッと変わっていて、目的の処理をv3に置き換えながら作るのが難しい(知識不足のため)。あとC++ももっと勉強しないといけない…。

コツコツやったことをメモしていこうと思います。v3系で。

現場からは以上です。</p>