カテゴリー
未分類

JavaでOAuth認証

今回はコードだらけの記事に。

TwitterのOAuth認証するJavaプログラムのコード。

Google App Engineなどでも使えます。サーブレッドなんで。

これは設定事項を任意に設定しておけば動作する(はず) 以下の画像の工程を最初から最後のデータ取得しクッキーに格納するところまで動作します。

http://cdn-ak.f.st-hatena.com/images/fotolife/y/yuroyoro/20100506/20100506190425_original.png

package com.appspot.axe1lyzelab;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URLEncoder;
import java.security.Key;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;

import javax.crypto.*;
import javax.crypto.spec.*;

import com.google.appengine.repackaged.com.google.common.util.Base64;
import javax.servlet.http.*;

@SuppressWarnings(“serial”)
public class OauthLogin extends HttpServlet {
    private HttpServletRequest req;
    private HttpServletResponse resp;
    private HttpSession session;
    String responseText = “”;
    static final String REQUSET_TOKEN_URL=”http://api.twitter.com/oauth/request_token”;
    static final String AUTHORIZE_URL=”http://api.twitter.com/oauth/authorize”;
    static final String ACCESS_TOKEN_URL=”http://api.twitter.com/oauth/access_token”;
    static final String APPLICATION_URL = “/”;
    static final String SELF_URL = “/oauth”;
    static final String CONSUMER_KEY=”xxxxxxxxxxxx”;
    static final String CONSUMER_SECRET=”xxxxxxxxxxxxx”;
    static final String SIGNATURE_METHOD=”HmacSHA1″;
    static final String VERSION = “1.0”;
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException{this.req=request;this.resp=response;session = req.getSession(true);
        if(req.getParameterMap().isEmpty()){
            session.invalidate();
            session=req.getSession();
            session.setAttribute(“oauth_token”,””);
            session.setAttribute(“oauth_token_secret”,””);
            session.setAttribute(“oauth_timestamp”,Long.toString(System.currentTimeMillis() / 1000));
            session.setAttribute(“oauth_nonce”,Long.toString(System.nanoTime()));
            try {getToken(REQUSET_TOKEN_URL);} catch (Exception e) {}
        }else if(req.getParameter(“oauth_verifier”)!=null){
            session.setAttribute(“oauth_verifier”,req.getParameter(“oauth_verifier”));
            try {getToken(ACCESS_TOKEN_URL);} catch (Exception e) {}
            Enumeration e = session.getAttributeNames();
            while(e.hasMoreElements()) {
                String key = (String)e.nextElement();
                responseText+=key+” : “+(String) session.getAttribute(key)+”<BR><BR>”;
            }responseText+=”<HR>”;
        }else{

        }
        resp.setContentType(“text/html; charset=utf-8”);
        resp.getWriter().write(“<html><head></head><body>”+responseText+”</body></html>”);
    }
    private void getToken(String from) throws MalformedURLException, IOException, NoSuchAlgorithmException, InvalidKeyException {
        URLConnection url = new URL(from + “?” + getRequestParameters(from)).openConnection();
        url.connect();
        HashMap<String,String> parsedResponse = parseResponse(getResponse(new BufferedReader(new InputStreamReader(url.getInputStream()))));
        if(from.equals(REQUSET_TOKEN_URL)){   
            session.setAttribute(“oauth_token_secret”,parsedResponse.get(“oauth_token_secret”));
            resp.sendRedirect(AUTHORIZE_URL+”?oauth_token=”+parsedResponse.get(“oauth_token”));
        }else if(from.equals(ACCESS_TOKEN_URL)){
            Iterator entries = parsedResponse.entrySet().iterator();
            while(entries.hasNext()){
                Entry entry = (Entry) entries.next();
                session.setAttribute((String)entry.getKey(),(String)entry.getValue());
            }
        }
    }
    private String getResponse(BufferedReader in) throws IOException{
        String str = “”;
        while (true) {
            String line = in.readLine();
            if (line == null) {break;}
            str+=line;
        }return str;
    }
    private String getRequestParameters(String URL) throws UnsupportedEncodingException, InvalidKeyException, NoSuchAlgorithmException, IllegalStateException {
        String OauthData = “”;
        OauthData += “oauth_consumer_key=” + CONSUMER_KEY;
        OauthData += “&oauth_nonce=” + session.getAttribute(“oauth_nonce”);
        OauthData += “&oauth_signature_method=HMAC-SHA1”;
        OauthData += “&oauth_timestamp=” + session.getAttribute(“oauth_timestamp”);
        OauthData += “&oauth_version=” + VERSION;
        if(req.getParameter(“oauth_token”)!=null){OauthData += “&oauth_token=” + req.getParameter(“oauth_token”);}
        if(!session.getAttribute(“oauth_token”).equals(“”)){OauthData += “&oauth_token=” + session.getAttribute(“oauth_token”);}
        OauthData += “&oauth_signature=”+getSignature(getSignatureBaseString(URL,OauthData), getKeyString());
        return OauthData;
    }

    private String getSignature(String signatureBaseString, String keyString)throws NoSuchAlgorithmException, InvalidKeyException,UnsupportedEncodingException, IllegalStateException {
        Mac mac = Mac.getInstance(SIGNATURE_METHOD);
        Key key = new SecretKeySpec(keyString.getBytes(),SIGNATURE_METHOD);
        mac.init(key);
        return URLEncoder.encode(Base64.encode(mac.doFinal(signatureBaseString.getBytes())),”UTF-8″);
    }

    private String getKeyString() {
        if(session.getAttribute(“oauth_token_secret”).equals(“”)) {return CONSUMER_SECRET + “&”;
        }else{return CONSUMER_SECRET + “&” + session.getAttribute(“oauth_token_secret”);}
    }

    private String getSignatureBaseString(String URL,String requestParameters)throws UnsupportedEncodingException {
        return “GET&” + URLEncoder.encode(URL, “utf-8”) + “&”+ URLEncoder.encode(requestParameters, “utf-8”);
    }

    private HashMap<String,String> parseResponse(String response) {
        HashMap<String,String> data = new HashMap<String,String>();
        if (response.indexOf(“&”) != -1) {
            String[] responseData = response.split(“&”);
            for (int i = 0; i <= responseData.length-1; i++) {
                String key = responseData[i].substring(0,responseData[i].indexOf(“=”));
                String value = responseData[i].substring(responseData[i].indexOf(“=”)+1);
                data.put(key, value);
            }
        }
        return data;
    }

}

カテゴリー
未分類

スマートフォン(Motorola Milestone 2)で寿司打(タイピング)

Motorola製スマートフォン Milestone2でフラッシュのタイピングゲーム「寿司打」をやってみました。

記録

正しく入力したキーの数 : 560回
平均キータイプ数 : 4.3回/秒
ミスタイプ数 : 34回

上記の結果では一分間の平均キー入力数は4.3*60=258キー。

一文字は約2キーなので258/2=129文字。

要するに一分間の平均入力文字数は129文字。

ちなみにワープロ検定一級レベルは1分間で70文字。

 

にしてもMilestone2はキーが硬い。指が痛い。

その上、今回は-(Fn+v)と!(Fn+A)を入力する時、Fnを押すとミス入力に買うとされてしまいタイムボーナスが途切れてしまった。

あと、ハードウェアの性能が追いついていなく、キーを押してから入力されるまでにラグがある。

そろそろMilestone2ではダメなのかな。

Milestone3はずっこけてくれたし、早くいい端末出てくれ!

 

動画は以下にあるが、ハイフンを押すときにすごくつらそうにしてるのがわかると思う。

物理QWERTYキーボード搭載は嬉しい。次はハイフンを独立させてやってくれ。

 

カテゴリー
未分類

Javaのソケット通信の切断を検知

ものすごく久々にJavaのコードを書いた。

コードを書いたのは大学の上級プログラミング(笑)以降かな。

 

まずは以下をご覧ください。(解像度が高すぎて文字が小さすぎるため、HD以上でご覧ください)

複数人のクライアントを扱うまでは簡単。

しかし問題なのはクライアントとの切断が検知できないため、切断してもその人のソケット変数が残ってしまう。

今回はそれを検知し、クローズしたソケットを自動的に削除するようにした。

ここで紹介するのは切断の検知方法だけにしておく。

 

あ、先に言っておくと、isClosed()やisConnected()では検知できません。

接続したらisConnectedがTrueに。close()により切断されたソケットはisClosed()でtrueが買えるようになっていて、接続状態を確認するものではありません。

サーバーと接続したクライアントアプリケーションが異常終了やCloseを使わずに切断された場合の検知は以下のように行うことができます。(かなり非効率ですが)

 

まずメインでデータのやり取りを行うソケット以外にもう一つ別のポートで通信状態をチェックします。

ソケット接続が確立したらソケットを閉じる。接続にはsetSoTimeoutで一定のタイムアウト時間を設定しておく。

これをループすることでクライアントが接続可能な状態かどうかを判断することができます。

タイムアウトしなければソケットを確立した瞬間破棄し、再接続を試します。

タイムアウトした場合そのネットワークは切断されているということが言えます。

 

クラスにまとめてDropBoxにアップロードしておきます。JavaDocはそのうち書きます。

これはもちろんサーバーサイド用とクライアントサイドで分ける必要があります。

両方とも、新しくオブジェクトをnewした瞬間から動作します。

 

サーバー側のファイル(ServerConnectionCheck)

void ServerConnectionCheck(String host, int port) //コンストラクタ

boolean isConnecting() //接続しているかどうか

void close() //終了

クライアント側のファイル(ClientConnectionCheck)

void ClientConnectionCheck(String host, int port) //コンストラクタ

void close() //終了

 

リンク切れの場合はご報告ください。

カテゴリー
未分類

会議通話しながらのゲームのライブ配信環境を作る

ゲームなどの配信をしてみたい、またはしたことがあるという方で自分の声を入れることができなかったり、会議通話しながらの配信ができないなどで困っている方がいると思います。

今回はその改善をするための簡単な手段を紹介。

コストとしては3000円程度が必要になります。(何も持っていない場合)

 

用意するもの

・ステレオミニプラグの差込口を分岐するやつ
・USBマイクのマイク部分が取り外せるやつ(これとか
・ステレオミニプラグケーブル

この三つが用意できたら、ステレオミニプラグの分岐するやつをパソコンのスピーカー端子に接続。

二つ差込口ができるから片方はそのままスピーカーをつなぐ。

もう片方にステレオミニプラグケーブルを接続し、USBマイクからマイクを取り外しそこに繋げる。

そうしたら、USBケーブルをPCに接続すればおk。

Windowsの標準入力をそのUSBマイクに設定し、Skypeのマイクはそのままサウンドカードや、オンボードチップの入力を使う。

そして設定でマイク入力をスピーカーから出すようにする。設定が難しいけどうまくやればハウリングはしない。

もしハウリングの問題が解決できないならスピーカーからの出力はやめ、ヘッドフォンを使う。

複数人でオンラインゲームやってても実況プレイができる。

カテゴリー
未分類

jQueryでiFrameを扱う

jQueryでiFrameを扱うのは意外と難しい。

コードで説明すると

<html>
<head>
<script src=”http://code.jquery.com/jquery-1.6.min.js”></script>
<script>
$(function(){

    //————————————–方法1
    $ifr = $(“<iframe id=’ifr’></iframe>”);
        //この段階ではIframeの内容は存在しない。

    $(“body”).append($ifr);
        //ここでIframeがロードされる。

    document.getElementById(“ifr”)
        .contentWindow
        .document.write(“<html><head></head><body></body></html>”);
        //これを書かないとGoogle Chrome以外は動作しない。

    $(“#ifr”).contents().find(“body”).append(“hoge”);
        //Ifrの内容に”hoge”を追加。

    //————————————–方法2
    $ifrObj = $(“<iframe></iframe>”).appendTo(document.body);
    $ifrObj.contents().ready(function(){
      $ifrObj.contents().find(“body”).append(“<div>hoge</div>”);
    });

});
</script>
</head>
<body>
</body>
</html>

jQuery自体はクロスブラウザ対策用に使えるかもしれないが、IfrのロードはChromeだと自動的にHTMLタグ、HEAD、Bodyが追加されているが、それ以外のブラウザだとReadyに時間がかかるか初期状態が空白のため検索ができない。

一応対処はこれぐらいかな。

たぶん方法2のほうが楽。

カテゴリー
未分類

EMBEDを非表示で再生する

ただiframeの中にEmbedを書き込みIframeを非表示にするだけ。

これで怪しいサイト作れちゃうね。Iframeって恐ろしい。

まぁそんなものよりもYoutubeなんかの動画をBGMとして使うには活用できそう。

結構面倒かもしれないけど、スクリプトも加えれるしね。

 

一応コード。面倒だからdocument.writeで書いちゃってます。

<iframe
    name=”test”
    width=”100%” height=”100%”
    style=”display:none;”>
</iframe>
<script>
test.document.write(“
    <embed
      src=’http://www.youtube.com/v/IGiYYIi-H8k?autoplay=1′
      width=’100%’ height=’100%’
      type=’application/x-shockwave-flash’
      allowscriptaccess=’always’
      allowfullscreen=’true’
      style=’padding:0px;margin:0px;’>
    </embed>”
);
</script>

カテゴリー
未分類

クロスドメインでJSを実行する方法

JSWOS(JavaScript Web OS)を作っていて思いついた。

どうやったらクロスドメインでデータを取得できるのか。

function crossDomainJS(url){
    $(“<script src='”+url+”‘></script>”)
        .bind(“onload”,function(){$(this).remove();})
        .appendTo(“head”);
}

これでcrossDomainJS()のパラメタにクロスドメインのJSのURLを入れても大丈夫。

これは引数でURLのJSファイルを実行し、読み込み完了時に要素を自動的に削除するというものです。

これでレンタルサバをJSモジュールの倉庫にできる。(大体のところでは規約違反になります)

カテゴリー
未分類

Android初期導入アプリとMilestone2を3日間(?)使った所感

やっとAndroidデビュー(笑)できました。

携帯端末としてAndroidを使うのは初めてでMilestone2でよかったかなと。

 

とりあえず導入したアプリ

・ADW – ランチャー
・OpenWnn フリック対応版
・Skype
・Dolphin Browser HD – ブラウザ
・Flash Player 10.3
・Digital Clock Widget(Red Wizard) – 時計ウィジェット
・Battery Widget(geekyouup) – バッテリー残量表示ウィジェット
・Temp+CPU V2 – システム情報表示ウィジェット
・Task Killer(Funny Android Games) – タスクキラー
・Uninstaller (Rhythm Software)
・SilentMode OnOff
・AutoRotate OnOff
・ES ファイルエクスプローラ - エクスプローラ
・Gmail – メール
・Youtube
・Google Map – 地図
・Google Reader – RSSリーダー
・Chrome to Phone
・Twitter
・DropBox – ネットワークストレージ
・Ustream

 

Milestone2(たぶんフルキーボード搭載端末)はOpenWnnフリック対応版かSimejiが入力切替が楽。

Simejiはスペースで変換できなかったのでOpenWnnフリック対応版を入れた。

 

タスクキラーはAdvanced Task Killerがよかったのだが、画面オフした時にタスクキルしてくれなかった。できるものを探した挙句上記のタスクキラーに。

 

jQuery(JavaScript)が動作するのは初期ブラウザとDolphinだけでしたのでブラウザはDolphin をインストール。

 

ESファイルエクスプローラーはDropBoxをサポートしてるのでDropBox公式アプリをいれなくてもDropBoxを利用できる。

けどなんか読み込みが遅いので公式を入れておいた。

カテゴリー
未分類

JavaScriptのループでブロックしない方法

久々の更新ですが、今回はかなり短いです。

for文やwhile文を使うと終わるまでブロックされてしまう。

回避する方法でConcurrentThreadなんてライブラリがあったような気がしますが使わなくても簡単にできます。

まぁ以下に書くものをライブラリにしたのがConcurrentThreadでしょうけど。

というわけで方法。

loop(条件式){}のloopはwhileやforで。

loop(条件式){setTimeout(function(){
  ループで行う内容
},0);}

まぁようするに一瞬待たせればいいだけです。

これでマルチスレッドなプログラムも簡単に作れそう。

カテゴリー
未分類

Ajax+PHPで擬似リアルタイム通信

以前にも同じようなことを書いたのですが、以前のやり方では不完全だったので書き直します。

 

reload(“./test.php”);//ここはテキストファイルじゃだめ。PHPじゃないとだめ。

function reload(url){
    $.get(url+”?”+new Date().getDate(),function(data){
        reload_func(data);
        setTimeout(function(){reload(url);},0);
    }
}

function reload_func(data){
    更新されたときの内容をちょめちょめ。
}

 

ゲットするURLはテキストファイルじゃだめです。これでキャッシュされなくなるので毎回そのときのデータを拾ってくることができます。これもmethods.jsに加えておこうかな。