Native Client(NaCl)をやってみる (7) - pp::WebSocket -
引き続き、Native Clientのサンプル読みつつ進めてみてます。今回はpp::WebSocketを使ってWebSocketサーバーにNative Client側から接続して云々するというサンプルを読んで進めてみました
ちなみに今まで「どのバージョンのpepperを使ってるのか」っていうの書いてなかったような気がしますので、一応検証ではpepper api version22
nacl.html
<html>
<body>
<button id="btn1">send</button>
<embed id="plugin" width="0" height="0" src="/sample.nmf" type="application/x-nacl" />
<script type="text/javascript">
(function(undefined) {
var plugin = document.querySelector("#plugin");
plugin.addEventListener("message", function(msg) {
var response = msg.data.split(",");
if (response[0] == 1) {
console.log(response[1]);
} else {
console.log("ERROR: " + response[1]);
}
});
document.querySelector("#btn1").addEventListener("click", function() {
// Native Client側にメッセージを送る
plugin.postMessage("fuga");
});
})();
</script>
<body>
</html>
HTMLとNative Client側はメッセージングでのみやりとりをする。WebSocket関係は全てNative Client内部で行う
sample.cc
#include "ppapi/cpp/instance.h"
#include "ppapi/cpp/module.h"
#include "ppapi/cpp/var.h"
#include "ppapi/cpp/websocket.h"
#include "ppapi/utility/completion_callback_factory.h"
class WebSocketInstance : public pp::Instance {
public:
explicit WebSocketInstance(PP_Instance instance) : pp::Instance(instance), websocket_(NULL), callback_(this) {
}
virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]) {
pp::CompletionCallback callback = callback_.NewCallback(&WebSocketInstance::OnConnect);
websocket_ = new pp::WebSocket(this);
websocket_->Connect(
pp::Var("ws://localhost:3000/echo"),
NULL,
0,
callback
);
return true;
}
virtual void HandleMessage(const pp::Var &var) {
if (!isConnected()) {
return;
}
websocket_->SendMessage(var);
}
private:
pp::WebSocket* websocket_;
pp::CompletionCallbackFactory<WebSocketInstance> callback_;
pp::Var data;
bool isConnected() {
if (websocket_) {
if (websocket_->GetReadyState() == PP_WEBSOCKETREADYSTATE_OPEN) {
return true;
}
}
PostMessage(pp::Var("0,disconncted"));
return false;
}
void OnConnect(int32_t result) {
if (!isConnected() || result != PP_OK) {
return;
}
Receive();
}
void Receive() {
if (!isConnected()) {
return;
}
pp::CompletionCallback callback = callback_.NewCallback(&WebSocketInstance::OnReceive);
websocket_->ReceiveMessage(&data, callback);
}
void OnReceive(int32_t result) {
if (result == PP_OK) {
if (data.is_string()) {
PostMessage(pp::Var("1," + data.AsString()));
}
}
Receive();
}
};
class WebSocketModule : public pp::Module {
public:
WebSocketModule() : pp::Module() {
}
virtual pp::Instance* CreateInstance(PP_Instance instance) {
return new WebSocketInstance(instance);
}
};
namespace pp {
Module* CreateModule() {
return new WebSocketModule();
}
}
でコンパイルして、上のnacl.htmlを動かすしてボタンを押すとここでもMojolicious側のHTMLな所でもWebSocket通信のメッセージング結果が返ってくる。で一度WebSocketサーバー側を落としちゃって見るとnacl.html側でdisconnectedって返ってくる