Hatena::ブログ(Diary)

hogeなlog

プロフィール

hogelog

hogelog

小室 直(こむろ すなお)。電気通信大学2003年入学。2010年修士卒業。プログラミングとかしてます。

カレンダー
1984 | 01 |
2006 | 07 | 08 | 09 | 10 | 11 | 12 |
2007 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2008 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2009 | 01 | 02 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 |
2010 | 01 | 06 | 08 | 09 | 10 | 11 | 12 |
2011 | 01 | 02 | 03 | 05 | 08 | 09 | 10 | 12 |
2012 | 01 | 04 | 06 |

December 20(Tue), 2011

[][] websocketで遊んでみた powered by Jetty 8

とりあえずベタベタにチャット的なものを。

f:id:hogelog:20111220013639p:image

ソースコードは https://github.com/hogelog/chatty に。

Windowsで動くWebSocketサーバをサクッと書くにはJavaでJetty使うのが一番楽だなあということがよくわかりました。rubyのアレとかpythonのソレとかこれとか、だいたいlibeventやらなんらかのネイティブライブラリを使っているので面倒。JettyでWebSocket使うには、pom.xmlを適当に仕上げて*1、ソース書いて、あとは

 $ mvn jetty:run

と叩くだけで依存するライブラリ落としてきて(ネイティブライブラリのビルドとかが始まることなしに)普通にサーバが動き始める。良い。

pom.xmlにjetty-websocketを記述。

        <dependency>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>jetty-websocket</artifactId>
            <version>8.1.0.RC1</version>
        </dependency>
@WebServlet("/chatty")
public class ChattyServlet extends WebSocketServlet {
    public WebSocket doWebSocketConnect(HttpServletRequest request, String protocol) {
        return new ChattyWebSocket();
    }
}
public class ChattyWebSocket implements WebSocket.OnTextMessage {
    public void onOpen(Connection connection);
    public void onClose(int closeCode, String message);
    public void onMessage(String data);
}

こんな感じで書く。WebSocket.OnTextMessage以外にもOnBinaryMessageとかもあるし普通に使いやすそう。

http://download.eclipse.org/jetty/stable-8/apidocs/org/eclipse/jetty/websocket/WebSocket.html

*1:それが面倒なんだろうけど

December 11(Sun), 2011

[] Java7触ってみる(1) ZipFS

package org.hogel.ArchiveTest;

import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;

import java.net.URI;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.HashMap;
import java.util.Map;

import org.junit.Test;

public class ZipTest {
    @Test
    public void zipfsのテスト() throws Exception {
        URI zipfile = URI.create("jar:file:/tmp/zipfs-test.zip");
        Map<String, String> env = new HashMap<>();

        // ZIPファイルを新規作成、ZIPエントリ名のエンコーディングはMS932(Shift-JIS)に
        env.put("create", "true");
        env.put("encoding", "MS932");
        try (FileSystem zipfs = FileSystems.newFileSystem(zipfile, env)) {
            // ほげ.txtファイルをZIPファイル内に作成
            Files.write(zipfs.getPath("ほげ.txt"), "ほげ".getBytes("MS932"), StandardOpenOption.CREATE);
        }

        // ZIPエントリほげ.txtというエントリ名がMS932(Shift−JIS)であることを確認
        byte[] zipdata = Files.readAllBytes(Paths.get("/tmp/zipfs-test.zip"));
        assertThat(new String(zipdata, "MS932").contains("ほげ.txt"), is(true));

        // 既存のZIPファイルの読み込みテスト
        env.put("create", "false");
        try (FileSystem zipfs = FileSystems.newFileSystem(zipfile, env)) {
            // ZIPファイル内のほげ.txtファイルを確認
            assertThat(new String(Files.readAllBytes(zipfs.getPath("ほげ.txt")), "MS932"), is("ほげ"));
        }
    }
}

ZIPへの追記、パス名のエンコーディング指定とかが標準ライブラリでできる。Java6でやりたければTrueZIPかな。まあJava7、ボチボチ細かく便利になっていていいですね。

[] Java7触ってみる(2) 削除済みファイルの読み書き

もしかしてできるようになっているのではと思ったらできるようになっていた喜ばしい。6まででやる方法あったんだろか? TrueZIPとか使えばできるかもしれない。

package org.hogel.NioTest;

import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.Writer;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;

import org.junit.Test;

public class NioTest {
    /**
     * 通るテスト
     */
    @Test
    public void 削除済みのファイルへの読み書き_nio() throws Exception {
        Path path = Paths.get("tmp");
        try (BufferedWriter writer = Files.newBufferedWriter(path, Charset.defaultCharset(), StandardOpenOption.CREATE)) {
            try (BufferedReader reader = Files.newBufferedReader(path, Charset.defaultCharset())) {
                writer.write("ほげ");
                assertThat(Files.deleteIfExists(path), is(true));
                assertThat(Files.exists(path), is(false));
                writer.write("ふが");
                writer.flush();
                String line = reader.readLine();
                assertThat(line, is("ほげふが"));
            }
        }
    }

    /**
     * 通らないテスト
     */
    @Test
    public void 削除済みのファイルへの読み書き_legacy() throws Exception {
        File file = new File("tmp");
        try (Writer writer = new FileWriter(file)) {
            try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
                writer.write("ほげ");
                assertThat(file.delete(), is(true)); // ここで失敗する
                assertThat(file.exists(), is(false));
                writer.write("ふが");
                writer.flush();
                String line = reader.readLine();
                assertThat(line, is("ほげふが"));
            }
        }
    }
}
トラックバック - http://d.hatena.ne.jp/hogelog/20111211
最近のコメント