0

NanoHTTPDでJavaアプリにwebサーバーを埋め込む

Javaで1ファイルで実装されたNanoHTTPDを触ってみた。
Apacheみたいなのが起動するんじゃなくて、自分のプロセスにwebサーバーの機能を埋め込むタイプ。

NanoHTTPD
https://github.com/elonen/nanohttpd


Androidで動かしている例も検索するとそれなりに出てくる。すんなり動くらしい。
Android上でWeb serverを動かしてみた – komamitsu.log
Androidアプリ開発に挑戦: Android で NanoHTTPD を使ってみる


とりあえずMacで試した。Androidではまだ試してない。
手元のファイルをHTTPで配信もできるし、リクエストのパスやメソッドやプロパティを読むことも出来る。
Androidのプログラムに埋め込めば、パソコンのwebブラウザからAndroidにアクセスして遠隔操作できて便利だと思う。


使い方

ドキュメントが無いけど実装がシンプルなのでgithubの本体のコードを見た。
new NanoHTTPD(8080, File(“.”));するだけで8080番で現在のディレクトリをdocument rootにしたhttpdが起動する。

カスタムするにはサンプルと同じくNanoHTTPDクラスを継承して、関数を自分で上書きしてしまえばいい。
主にserve(String uri, String method, Properties header, Properties parms, Properties files)を上書きする事になると思う。

本体のコードを見るとserveからserveFile関数を呼び出しているので、自分でserve関数を定義し直したらそこからfileServeも呼び出しなおしてあげないとファイル配信できなくなる。
(同梱されていたサンプルのHelloServer.javaではfileServeが動いていない)


webブラウザからMacを遠隔操作する例



サンプルのHelloServer.javaを改造してみた。特定のパス(/goと/stop)にリクエストが来たらMacのsayコマンドで「ゴー」「ストップ」と喋らせる。
それ以外のパスへのリクエストは、dataディレクトリ内のファイルを返すようにしてみた。
Androidのプログラムに埋め込む時は、SDカードやassetsのディレクトリでファイル配信すればいいと思う。
import java.io.*;
import java.util.*;

public class HelloServer extends NanoHTTPD
{
public HelloServer() throws IOException
{
super(8080, null);
}

public Response serve( String uri, String method, Properties header, Properties parms, Properties files )
{
System.out.println( method + " '" + uri + "' " );
if(uri.equals("/go")){
try{
Runtime.getRuntime().exec("/usr/bin/say go");
}catch(java.io.IOException e){
System.err.println(e);
}
System.out.println("go!!!!");
return new NanoHTTPD.Response( HTTP_OK, MIME_HTML, "go");
}
if(uri.equals("/stop")){
try{
Runtime.getRuntime().exec("/usr/bin/say stop");
}catch(java.io.IOException e){
System.err.println(e);
}
System.out.println("stop!!!!");
return new NanoHTTPD.Response( HTTP_OK, MIME_HTML, "stop");
}
return serveFile(uri, header, new File("./data"), true);
}


public static void main( String[] args )
{
try
{
new HelloServer();
}
catch( IOException ioe )
{
System.err.println( "Couldn't start server:" + ioe );
System.exit( -1 );
}
System.out.println( "Listening on port 8080. Hit Enter to stop." );
try { System.in.read(); } catch( Throwable t ) {};
}
}


dataというディレクトリを作ってその中にindex.htmlとして保存する。
ボタンが2つ並んでるだけだけど、押したらMacが「ゴー」「ストップ」とか喋る。
<html>
<head>
<script src='//ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js' type='text/javascript'></script>
<script type="text/javascript">
$(function(){
console.log("start");

$("#go").click(function(){
console.log("go button");
$.get("/go");
});
$("#stop").click(function(){
console.log("stop button");
$.get("/stop");
});

});
</script>
</head>
<body>
<h1>remote controll</h1>
<div>
<input type="button" value="go" id="go"></input>
<input type="button" value="stop" id="stop"></input>
</div>
</body>
</html>

1

Raspberry Pi + mjpg-streamerでwebcam動画配信


HTMLにimgタグで埋め込んでwebブラウザで見れる


これそのままやってみた → Raspberry Pi に Webカメラを接続して動画を配信してみる Chick Lab
ロボット作ったりしててすごい Raspberry Piでロボットを作る Chick Lab


mjpg-streamerインストール

sudo apt-get install subversion libjpeg-dev imagemagick
svn co https://mjpg-streamer.svn.sourceforge.net/svnroot/mjpg-streamer mjpg-streamer
cd mjpg-streamer/mjpg-streamer
make


カメラ起動


20fpsで配信するとCPU90%使っちゃってApache2を殺したりしたので、2fpsにしたら10%前後になった。
./mjpg_streamer -i "./input_uvc.so -f 2 -r 320x240 -d /dev/video0 -y" -o "./output_http.so -w ./www -p 8080"

port 8080 で起動する。


普通にHTMLにimgタグで埋め込んだら動画になった。
<html>
<body>
<h1>Raspberry Pi</h1>
<img src="http://192.168.1.6:8080/?action=stream">
</body>
</html>

0

Raspberry PiにWiFi付けた

PlanexのUSB WiFiを付けた。
RaspberryPi USB WiFi




全然飛び出ない
RaspberryPi USB WiFi


WiFi設定


/etc/network/interfaces で設定しようとしたが、ウチはWPAかつステルスなWiFi APなので、設定が面倒でやめた。

wlan0の設定を全部消して、
auto lo

iface lo inet loopback
iface eth0 inet dhcp
これだけにした。


GUIのネットワークマネージャで設定する。

インストール
sudo apt-get remove wpagui
sudo apt-get install wpasupplicant network-manager network-manager-gnome


右下のネットワークっぽい設定からネットワークに接続できる。
うちはWPA2かつ不可視のネットワークなので、”connect to hidden wireless network”というメニューから接続できた。
“create new wireless network”から設定しようとするとなぜかWPA2が選択できない。
RaspberryPi USB WiFi


複数WiFi APを登録しておいたら、起動時に使える方に接続してくれるようになった。
RaspberryPi USB WiFi


HDMIケーブルとか全部外して再起動させて、sshで接続できるのを確認して完了。
ついでに気温とか明るさをツイートするやつもRaspberry Piで動かすようにした。


ケーブルが少なくなってすっきりした
R0020609

0

Raspberry Pi + Firmata + Arduino Duemillanoveのバグを直した

昨日のこれ直した

Duemillanoveは一度使うと抜き差ししないと認識しなくなるバグが発覚した。あとで直す。
UNOは問題ない。

橋本商会 » Raspberry PiでRuby/Arduino/Twitter/webcam


Arduino Firmataのv0.1.6が既にrubygemsにリリースされています

gem install arduino_firmata
でアップデートしてお楽しみください


バグ内容

色々試してたら、2回目以降はArduinoのリセットボタンを押せば認識する事に気づいた。

firmataデバイスがちゃんと認識しているかを確認する手段としてデバイスから送られてくるバージョン番号を使っている。
バージョン番号はArduino起動時に送られるだけで、Macや俺の持ってるUbuntuネットブックではシリアルポート接続時にリセットがかかるので2回目も使えていたらしい。Arduino UNOの場合はMacでもRaspberry Piでも接続時にリセットかかるので動いていた。

Raspberry Piでは接続時にリセットがかからないので、シリアルポート開いた直後にバージョン番号をリクエストするだけでバージョン返してくれるようになった。


これならもしかしたら、以前挫折したMSP430 LaunchPadのFirmata化もできるかも

0

Raspberry PiでMSP430 LaunchPad開発

Raspberry Piにはraspbianを入れてある。


まずシリアルデバイスが認識されてないので

sudo apt-get install libusb-dev
で /dev/ttyACM0 が出るけど通信できない。Macだとできるのだが・・


RubyのSerialPort gemで通信するとエラーがでる
Input/output error - /dev/ttyACM0


開発ツールを入れてみた
sudo apt-get install binutils-msp430 mspdebug gcc-msp430
mspgccとmspdebugを使った開発、このへんはできた
橋本商会 » MacにMSP430 LaunchPadの開発環境入れて、LEDピコピコさせた


シリアルポートで通信できないのが悲しいなあ