ブラウザ等、クライアント側
プログレスバーを追加してみた。
http://www.html5.jp/library/progress.html
<!DOCTYPE html>
<html>
<head>
<title>Websocket client</title>
<link href="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.1/css/bootstrap-combined.min.css" rel="stylesheet">
<script src="http://code.jquery.com/jquery.js"></script>
<script src="../html5jp/progress.js"></script>
</head>
<body>
<div class="container">
<h1 class="page-header">Websocket client</h1>
<form action="" class="form-inline" id="connectForm">
<div class="input-append">
<input type="text" class="input-large" value="ws://192.168.1.63:8088/echo" id="wsServer">
<button class="btn" type="submit" id="connect">Connect</button>
<button class="btn" disabled="disabled" id="disconnect">Disconnect</button>
</div>
</form>
<form action="" id="sendForm">
<div class="input-append">
<input class="input-large" type="text" placeholder="message" id="message" disabled="disabled">
<button class="btn btn-primary" type="submit" id="send" disabled="disabled">send</button>
</div>
</form>
<form action="" id="ledForm">
<div class="input-append">
<button class="btn" value="1" disabled="disabled" id="led1">LED1</button>
<button class="btn" value="2" disabled="disabled" id="led2">LED2</button>
</div>
</form>
<hr>
<div id="sample"></div>
<hr>
<form name="mform">
<textarea name="messages" rows="5" cols="50"></textarea>
</form>
<hr>
<ul class="unstyled" id="log"></ul>
</div>
<script type="text/javascript">
$(document).ready(function() {
var ws;
var p = { to:50 };
var o = new html5jp.progress("sample",p);
o.draw();
$('#connectForm').on('submit', function() {
if ("WebSocket" in window) {
ws = new WebSocket($('#wsServer').val());
ws.binaryType = 'arraybuffer';
ws.onopen = function() {
$('#log').append('<li><span class="badge badge-success">websocket opened</span></li>');
$('#wsServer').attr('disabled', 'disabled');
$('#connect').attr('disabled', 'disabled');
$('#disconnect').removeAttr('disabled');
$('#led1').removeAttr('disabled');
$('#led2').removeAttr('disabled');
$('#message').removeAttr('disabled').focus();
$('#send').removeAttr('disabled');
};
ws.onerror = function() {
$('#log').append('<li><span class="badge badge-important">websocket error</span></li>');
};
ws.onmessage = function(event) {
if(typeof event.data == 'string') {
var str = "String:";
str += event.data;
var percent = parseInt(event.data);
if(percent != NaN){
o.set_val(percent);
}
} else if(typeof event.data == 'object') {
var byteArray = new Uint8Array(event.data);
var str = "Object:";
for( var n = 0;n < byteArray.length;n++){
str += " 0x" + ("0" + byteArray[n].toString(16)).slice(-2);
}
} else {
var str = "Unknown:";
}
var num = (document.mform.messages.value.match(/\n/g) || []).length + 1;
if(num > 4){
document.mform.messages.value = document.mform.messages.value.replace(/[\w\W]+?\n+?/,"");
}
document.mform.messages.value = document.mform.messages.value + '\r\n'+ str;
//$('#log').append('<li>received: <span class="badge">' + str + '</span></li>');
};
ws.onclose = function() {
$('#log').append('<li><span class="badge badge-important">websocket closed</span></li>');
$('#wsServer').removeAttr('disabled');
$('#connect').removeAttr('disabled');
$('#disconnect').attr('disabled', 'disabled');
$('#message').attr('disabled', 'disabled');
$('#send').attr('disabled', 'disabled');
};
} else {
$('#log').append('<li><span class="badge badge-important">WebSocket NOT supported in this browser</span></li>');
}
return false;
});
$('#sendForm').on('submit', function() {
var message = $('#message').val();
ws.send(message);
$('#log').append('<li>sended: <span class="badge">' + message + '</span></li>');
return false;
});
$('#led1').on('click', function() {
var buffer = new ArrayBuffer(2);
var byteArray = new Uint8Array(buffer);
byteArray[0] = 0xf8;
byteArray[1] = 0x01;
var str = "";
for( var n = 0; n<byteArray.length;n++){
str += " 0x"+ ("0" + byteArray[n].toString(16)).slice(-2);
}
ws.send(buffer);
var num = (document.mform.messages.value.match(/\n/g) || []).length + 1;
if(num > 4){
document.mform.messages.value = document.mform.messages.value.replace(/[\w\W]+?\n+?/,"");
}
document.mform.messages.value = document.mform.messages.value + '\r\n'+ str;
return false;
});
$('#led2').on('click', function() {
var message = $(this).attr('value');
ws.send(message);
var num = (document.mform.messages.value.match(/\n/g) || []).length + 1;
if(num > 4){
document.mform.messages.value = document.mform.messages.value.replace(/[\w\W]+?\n+?/,"");
}
document.mform.messages.value = document.mform.messages.value + '\r\n'+ message;
return false;
});
$('#disconnect').on('click', function() {
ws.close();
return false;
});
});
</script>
</body>
</html>
RX63N側サーバー
1)受信したら、送り返す動作。
バイナリとテキストを区別しています。
2)定期的にテキストで送信。
freecounterの値
------------
...略
#include "websocket.h"
#define BUF_LEN 512
void clientWorker(ID cepid);
/******************************************************************************
Exported global variables and functions (to be accessed by other files)
******************************************************************************/
void error(const char *msg)
{
// perror(msg);
return;
// exit(EXIT_FAILURE);
}
int safeSend(ID cepid, const uint8_t *buffer, size_t bufferSize)
{
ER written;
written = tcp_snd_dat(cepid, buffer, bufferSize, 100);
if (written < 0) {
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
static uint8_t freecounter=0;
void clientWorker(ID cepid)
{
uint8_t buffer[BUF_LEN];
uint8_t txbuffer[12];
int i;
memset(buffer, 0, BUF_LEN);
size_t readedLength = 0;
size_t frameSize = BUF_LEN;
enum wsState state = WS_STATE_OPENING;
uint8_t *data = NULL;
size_t dataSize = 0;
enum wsFrameType frameType = WS_INCOMPLETE_FRAME;
struct handshake hs;
nullHandshake(&hs);
#define prepareBuffer frameSize = BUF_LEN; memset(buffer, 0, BUF_LEN);
#define initNewFrame frameType = WS_INCOMPLETE_FRAME; readedLength = 0; memset(buffer, 0, BUF_LEN);
while (frameType == WS_INCOMPLETE_FRAME) {
ER readed = tcp_rcv_dat(cepid, buffer+readedLength, BUF_LEN-readedLength, 100);
if(readed == E_TMOUT){
readed = sprintf((char *)txbuffer,
"%d",freecounter);
freecounter++;
if(freecounter > 99) freecounter = 0;
prepareBuffer;
wsMakeFrame(txbuffer, readed, buffer, &frameSize, WS_TEXT_FRAME);
if (safeSend(cepid, buffer, frameSize) == EXIT_FAILURE)
break;
initNewFrame;
readed=0;
} else if (readed <= 0) {
return;
}
if(readed){
printk("(%3d)",readed);
for(i=0;(i<16) && (i < readed);i++){
printk(" %02x",buffer[i]);
}
printk("\n");
}
readedLength+= readed;
if (state == WS_STATE_OPENING) {
frameType = wsParseHandshake(buffer, readedLength, &hs);
} else {
dataSize=0;
frameType = wsParseInputFrame(buffer, readedLength, &data, &dataSize);
if(dataSize){
printk("[%3d]",dataSize);
for(i=0;(i<16) && (i < dataSize);i++){
printk(" %02x",data[i]);
}
printk("\n");
}
}
if ((frameType == WS_INCOMPLETE_FRAME && readedLength == BUF_LEN) || frameType == WS_ERROR_FRAME) {
if (frameType == WS_INCOMPLETE_FRAME)
printk("buffer too small\n");
else
printk("error in incoming frame\n");
if (state == WS_STATE_OPENING) {
prepareBuffer;
frameSize = sprintf((char *)buffer,
"HTTP/1.1 400 Bad Request\r\n"
"%s%s\r\n\r\n",
versionField,
version);
safeSend(cepid, buffer, frameSize);
break;
} else {
prepareBuffer;
wsMakeFrame(NULL, 0, buffer, &frameSize, WS_CLOSING_FRAME);
if (safeSend(cepid, buffer, frameSize) == EXIT_FAILURE)
break;
state = WS_STATE_CLOSING;
initNewFrame;
}
}
if (state == WS_STATE_OPENING) {
//assert(frameType == WS_OPENING_FRAME);
if (frameType == WS_OPENING_FRAME) {
// if resource is right, generate answer handshake and send it
if (strcmp(hs.resource, "/echo") != 0) {
frameSize = sprintf((char *)buffer, "HTTP/1.1 404 Not Found\r\n\r\n");
if (safeSend(cepid, buffer, frameSize) == EXIT_FAILURE)
break;
}
prepareBuffer;
wsGetHandshakeAnswer(&hs, buffer, &frameSize);
if (safeSend(cepid, buffer, frameSize) == EXIT_FAILURE)
break;
state = WS_STATE_NORMAL;
initNewFrame;
}
} else {
if (frameType == WS_CLOSING_FRAME) {
if (state == WS_STATE_CLOSING) {
break;
} else {
prepareBuffer;
wsMakeFrame(NULL, 0, buffer, &frameSize, WS_CLOSING_FRAME);
safeSend(cepid, buffer, frameSize);
return;
}
} else if (frameType == WS_TEXT_FRAME) {
uint8_t *recievedString = NULL;
recievedString = malloc(dataSize+1);
//assert(recievedString);
memcpy(recievedString, data, dataSize);
recievedString[ dataSize ] = 0;
prepareBuffer;
wsMakeFrame(recievedString, dataSize, buffer, &frameSize, WS_TEXT_FRAME);
if (safeSend(cepid, buffer, frameSize) == EXIT_FAILURE)
break;
initNewFrame;
} else if (frameType == WS_BINARY_FRAME) {
uint8_t *recievedString = NULL;
recievedString = malloc(dataSize+1);
//assert(recievedString);
memcpy(recievedString, data, dataSize);
recievedString[ dataSize ] = 0;
prepareBuffer;
wsMakeFrame(recievedString, dataSize, buffer, &frameSize, WS_BINARY_FRAME);
if (safeSend(cepid, buffer, frameSize) == EXIT_FAILURE)
break;
initNewFrame;
}
}
} // read/write cycle
}
void websocket_srv(ID id)
{
ID cepid, repid;
ER ercd;
T_IPV4EP dst_addr;
/* setting of reception point and communucation end point */
cepid = id;
repid = id;
/* TCP wait connection */
printk("wait tcp_acp_cep\n");
ercd = tcp_acp_cep(cepid, repid, &dst_addr, TMO_FEVR);
printk("connect\n");
if (ercd == E_OK)
{
clientWorker(cepid);
}
/* shutdown */
tcp_sht_cep(cepid);
tcp_cls_cep(cepid, 100);
printk("shutdown\n");
return;
}
0 件のコメント:
コメントを投稿