LoginSignup
5
6

More than 5 years have passed since last update.

JettyでWebSocketを使う(IntelliJの設定等も説明)

Last updated at Posted at 2015-10-18

NetBeansやらEclipseでやってる例は簡単に見つけることが出来ましたが、IntelliJでやってる記事が見当たらない感じだったので備忘録として詳しく書いておきます。
あと、ここではjarで出力して動かすまでの手順を説明をしていきます。

環境

  • MacOSX El Capitan
  • IntelliJ IDEA 14.1.5 (Ultimate)
  • Jetty 9.2.13

WebSocketを使う前の準備

WebSocketを使うために、Jettyを動かす必要があるのでここではJettyを動かす環境の作成について説明します。

プロジェクトの作成

まず、IntelliJを立ち上げます。
そしてプロジェクト新規作成。
以下のように"Web Application"にチェックを入れます。
スクリーンショット 2015-10-18 21.17.28.png

プロジェクト名は適当に。
スクリーンショット 2015-10-18 21.19.46.png

ライブラリを追加

プロジェクトの生成が完了したら、ライブラリを入れるディレクトリを作成します。
スクリーンショット 2015-10-18 21.20.39.png
ここでは"libs"とします。
スクリーンショット 2015-10-18 21.21.41.png
ディレクトリを作成したら、以下のページから2つのjarファイルをダウンロードします。
jetty-all-9.2.13.v20150730.jar
javax.servlet-api-3.1.0.jar
ダウンロードしたら、先ほど作ったライブラリを入れるディレクトリ(今回はlibs)にファイルを入れます。
すると以下のようになります。
スクリーンショット 2015-10-18 21.27.44.png
そして、以下のアイコンから"Project Structure"を開きます。
スクリーンショット 2015-10-18 21.30.42.png
開いたら、左のペインから"Modules"を選択し、"Dependencies"タブを開きます。
スクリーンショット 2015-10-18 21.30.48.png
すると、下部「+」ボタンがあるのでクリックし、"Jars or directories..."をクリックします。
スクリーンショット 2015-10-18 21.30.56.png
そして、先ほど作成したライブラリディレクトリ(libs)を選択します。
スクリーンショット 2015-10-18 21.34.46.png
そうすると以下の画面になると思うので、「OK」を押して完了です。
スクリーンショット 2015-10-18 21.34.56.png
以上で、WebSocketを使う準備ができました。

プログラムを書く

前項でJettyを動かす事が出来るようになったので、次はWebSocketを使う為にプログラムを記述していきます。

今回はjarとして動かすのでmain()を作ります。

Main.java
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.HandlerList;
import org.eclipse.jetty.server.handler.ResourceHandler;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;

public class Main {

    public static void main(String[] args){
        Server server = new Server(8080);
        ResourceHandler resourceHandler = new ResourceHandler();

        WebSocketServletImpl wsservlet = new WebSocketServletImpl();
        ServletContextHandler contextHandler = new ServletContextHandler(ServletContextHandler.SESSIONS);
        contextHandler.addServlet(new ServletHolder(wsservlet), "/");

        HandlerList handlers = new HandlerList();
        handlers.setHandlers(new Handler[] { resourceHandler, contextHandler });
        server.setHandler(handlers);

        try {
            server.start();
            System.out.println("Server Start");
        } catch (InterruptedException e) {
            System.out.println(e.getMessage());
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }
}
WebSocketServletImpl.java

import org.eclipse.jetty.websocket.servlet.WebSocketServlet;
import org.eclipse.jetty.websocket.servlet.WebSocketServletFactory;

public class WebSocketServletImpl extends WebSocketServlet {
    private static final long serialVersionUID = 1L;

    @Override
    public void configure(WebSocketServletFactory factory) {
        factory.register(WebSocketSample.class);
    }
}

WebSocketSample.javaは、@WebSocketアノテーションを忘れずに。

WebSocketSample.java

import org.eclipse.jetty.websocket.api.Session;
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose;
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect;
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage;
import org.eclipse.jetty.websocket.api.annotations.WebSocket;

@WebSocket //付け忘れに注意
public class WebSocketSample {
    private Session session;

    @OnWebSocketConnect
    public void onConnect(Session session) {
        this.session = session;
        WebSocketBroadcaster.getInstance().join(this);
    }

    @OnWebSocketMessage
    public void onText(String message) {
        WebSocketBroadcaster.getInstance().sendToAll(message);
    }

    @OnWebSocketClose
    public void onClose(int statusCode, String reason) {
        WebSocketBroadcaster.getInstance().bye(this);
    }

    public Session getSession(){
        return this.session;
    }
}

WebSocketBroadcaster.java
import java.util.ArrayList;
import java.util.List;

public class WebSocketBroadcaster {

    private static WebSocketBroadcaster INSTANCE = new WebSocketBroadcaster();
    private List<WebSocketSample> clients = new ArrayList<WebSocketSample>();

    private WebSocketBroadcaster(){}

    protected static WebSocketBroadcaster getInstance(){
        return INSTANCE;
    }

    //接続時に呼ばれる
    protected void join(WebSocketSample socket){
        clients.add(socket);
    }

    //切断時に呼ばれる
    protected void bye(WebSocketSample socket){
        clients.remove(socket);
    }

    //全ソケットにmessageを送信
    protected void sendToAll(String message){
        for(WebSocketSample member: clients){
            member.getSession().getRemote().sendStringByFuture(message);
        }
    }

}
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">

    <servlet>
        <display-name>WebSocketSample</display-name>
        <servlet-name>WebSocketSample</servlet-name>
        <servlet-class>WebSocketServletImpl</servlet-class>
        <load-on-startup>0</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>WebSocketSample</servlet-name>
        <url-pattern>/WebSocketSample/*</url-pattern>
    </servlet-mapping>
</web-app>

記述したら以下のようになると思います。
スクリーンショット 2015-10-18 23.39.01.png

おまけ(?)

Mainにサーバを立ち上げる記述があります。

server.start();

サーバが立ち上がった後に、以下のコードを実行する事で接続中の全クライアントに対してメッセージを送ることが出来ます。

WebSocketBroadcaster.getInstance().sendToAll("Hello World!");

実行

上部にある実行ボタンの横のプルダウンメニュの"Edit Configurations"を選択します。
(ここでは既にMainがありますが気にしないで下さい)
スクリーンショット 2015-10-18 23.47.28.png
下図のように「+」をクリックして"Application"をクリックします。
スクリーンショット 2015-10-18 23.49.56.png
名前とMainクラスを設定し、OKをクリックします。
スクリーンショット 2015-10-18 23.50.54.png
そして、実行ボタンを押すとサーバが起動します。
スクリーンショット 2015-10-18 23.51.56.png

WebSocket接続

サーバを動かした状態で、Chromeの拡張を入れて実際に動作を確認してみます。
Simple WebSocket Client

URLに「ws://localhost:8080/WebSocketSample」を設定してOpenすると接続できます。
接続出来たら、Requestからメッセージを送ってそのまま戻ってくると成功です。
スクリーンショット 2015-10-18 23.57.19.png

jarを生成

"Project Structure"を開き、左のペインから"Artifacts"をクリックして「+」をクリックし、以下を参考に選択します。
スクリーンショット 2015-10-18 23.58.07.png

Main Classを設定します。(ここではModule名などがJettyWS2になってますが気にしないで下さい。)
スクリーンショット 2015-10-18 23.58.15.png
設定が終わったら、Buildします。
スクリーンショット 2015-10-19 0.01.05.png
あとは、jarが生成されるのでそれを叩けばサーバが動きます。

5
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
6