メインコンテンツまでスキップ
バージョン: 20 R6

WebSocketServer

WebSocketServer クラスを使って、4D で WebSocketサーバーを作成および設定することができます。 4D WebSocketサーバーがアクティブになると、WebSocketConnection クラス を使用して 4D とクライアント間で WebSocket 接続を開き、使用することができます。

履歴
リリース内容
20追加
WebSocket サーバーについて

WebSocketプロトコルは、WebSocketサーバーとクライアント (Webブラウザーなど) の間の双方向通信のチャンネルを提供します。 WebSocketサーバーの詳細については、Wikipedia のページ を参照ください。

参照

4D WebSocketサーバーについては、こちらのブログ記事 も参照ください。

要件

4D で WebSocketサーバーを作成し、扱うには、4Dビルトインクラスを 2つ使用する必要があります。

  • このクラス (4D.WebSocketServer) は、サーバー自体を管理するためのものです。
  • 4D.WebSocketConnection クラスを使用して、接続とメッセージを管理します。

さらに、2つのユーザークラスを作成し、コールバック関数を定義する必要があります:

  • サーバー接続を処理するためのユーザークラス
  • メッセージを処理するためのユーザークラス

接続を維持するため、WebSocketサーバーの作成ワーカー 内にておこなう必要があります。

4D Webサーバー を起動しておく必要があります。

例題

この基本的な例では、WebSocketサーバーはメッセージを大文字で返します。

  1. ワーカーを使用して (必須) WebSocketサーバーを作成し、サーバー接続処理用のユーザークラスをパラメーターとして渡します。
    // ユーザークラスのインスタンスを作成します
// これが、サーバーへの接続を処理します
var $handler:cs.myServerHandler
$handler:=cs.myServerHandler.new()

CALL WORKER("WebSocketServer"; Formula(wss:=4D.WebSocketServer.new($handler)))
// WebSocket を変数 (wss) に代入しておくことで
// あとで wss.terminate() の呼び出しが可能になります
  1. サーバーへの接続を処理するためのコールバック関数を含む myServerHandler ユーザークラスを定義します:
// myServerHandler クラス

Function onConnection($wss : Object; $event : Object) : Object
// ユーザークラスのインスタンスを返します
// このインスタンスがサーバーへの接続を処理します
return cs.myConnectionHandler.new()
  1. メッセージを処理するためのコールバック関数を含む myConnectionHandler ユーザークラスを定義します:
// myConnectionHandler クラス

Function onMessage($ws : 4D.WebSocketConnection; $message : Object)
// メッセージを大文字に変えて送信します
$ws.send(Uppercase($message.data))

クライアントサイド JS

WebSocket 接続を処理するクライアントサイドの Javascriptコードの例については、このブログの記事 を参照ください。

WebSocketServer オブジェクト

WebSocketサーバーオブジェクトは、以下のプロパティと機能を提供します:

.connections : Collection
WebSocketサーバーが処理しているカレントの接続をすべて格納します
.dataType : Text
受信または送信されるデータの型
.handler : Object
WebSocketサーバーの開始に使用された WSSHandler オブジェクトを取得するアクセサーです
.path : Text
WebSocketサーバーにアクセスするためのパスのパターンです
.terminate()
.terminate( timeout : Integer )

WebSocketサーバーを終了します
.terminated : Boolean
WebSocketサーバーが終了している場合には true です

4D.WebSocketServer.new()

4D.WebSocketServer.new( WSSHandler : Object { ; options : Object } ) : 4D.WebSocketServer

引数説明
WSSHandlerObject->WebSocketサーバー用コールバックを宣言しているユーザークラスのオブジェクト
optionsObject->WebSocket の設定パラメーター
戻り値4D.WebSocketServer<-新しい WebSocketServer オブジェクト

4D.WebSocketServer.new() 関数は、指定した WSSHandler コールバックと、options の設定 (任意) を使用して WebSocketサーバーを作成および起動し、4D.WebSocketServer オブジェクトを返します。

この関数を呼び出すには、4D Webサーバー が起動されている必要があります。 WebSocketサーバーの ホストポート は、4D Webサーバーのホストとポートと同じです。

WSSHandler 引数

WSSHandler 引数には、WebSocketサーバーでイベント (主に接続イベント) が発生するたびに呼び出されるユーザークラスのインスタンスを渡します。 このクラスでは、以下のコールバック関数を定義します (onConnection のみ必須):

プロパティ説明デフォルト
onConnectionFunction(必須) 新規クライアント接続が開始した時のコールバック (後述参照)undefined
onOpenFunctionWebSocketサーバーが起動した時のコールバック (後述参照)undefined
onTerminateFunctionWebSocketサーバーが終了した時のコールバック (後述参照)undefined
onErrorFunctionエラーが発生した時のコールバック (後述参照)undefined

WSHandler.onConnection(WSServer : Object ; event : Object) : Object | null

引数説明
WSServer4D.WebSocketServer<-カレントの WebSocketサーバーオブジェクト
eventObject<-引数
typeText"connection"
requestObjectrequest オブジェクト。 接続要求に関する情報を格納します (後述参照)
戻り値Object->connectionHandler オブジェクト (後述参照)。 この関数が connectionHandler オブジェクトを返す場合、4D.WebSocketConnection オブジェクト が自動的に作成され、カレント接続のコレクション に追加されます。 その後、このオブジェクトは connectionHandler オブジェクトの各関数に引数として受け取られます。 戻り値が null または undefined の場合、接続は解除されます。

このコールバックは、ハンドシェイクが完了したときに呼び出されます。 WebSocket 接続を作成するためには、有効な connectionHandler オブジェクト を指定して呼び出す必要があり、そうでない場合は接続がキャンセルされます。

WSHandler.onOpen(WSServer : Object ; event : Object)

引数説明
WSServer4D.WebSocketServer<-カレントの WebSocketサーバーオブジェクト
eventObject<-引数
typeText"open"

WebSocketサーバーが起動したときに発生するイベントです。

WSHandler.onTerminate(WSServer : Object ; event : Object)

引数説明
WSServer4D.WebSocketServer<-カレントの WebSocketサーバーオブジェクト
eventObject<-引数
typeText"terminate"

HTTPサーバーまたは WebSocketサーバーが終了したときに発生するイベントです。

WSHandler.onError(WSServer : Object ; event : Object)

引数説明
WSServer4D.WebSocketServer<-カレントの WebSocketサーバーオブジェクト
eventObject<-引数
typeText"error"
errorsCollection実行エラーの場合、4Dエラースタックのコレクション
  • [].errCode (number) - 4Dエラーコード
  • [].message (text) - 4Dエラーの説明
  • [].componentSignature (text) - エラーを返した内部コンポーネントの署名
  • WebSocketサーバーでエラーが発生したときに発生するイベントです。

    WSSHandler クラスの例

    この基本的なチャット機能の例では、WSSHandler クラスを使って WebSocket サーバー接続を管理する方法を説明します。

    // myWSServerHandler クラス 

    Function onConnection($wss : Object; $event : Object) : Object

    If (VerifyAddress($event.request.remoteAddress))
    // VerifyAddress メソッドはクライアントのアドレスを検証します
    // 返される WSConnectionHandler オブジェクトは、この接続に関連する
    // 4D.WebSocketConnection オブジェクトをインスタンス化するために
    // 4D によって使用されます
    return cs.myConnectionHandler.new()
    // connectionHandler オブジェクト参照
    Else
    // 接続は解除されます
    return Null
    End if

    Function onOpen($wss : Object; $event : Object)
    LogFile("*** サーバー起動")

    Function onTerminate($wss : Object; $event : Object)
    LogFile("*** サーバー終了")

    Function onError($wss : Object; $event : Object)
    LogFile("!!! サーバーエラー: "+$event.errors.first().message)

    request オブジェクト

    request オブジェクトには、次のプロパティが格納されています:

    引数説明
    headersObjectクライアントの HTTP GET リクエスト。 headers.key=value (同じ key を複数指定する場合、value にコレクションを使用できます)
    queryObjectURL 引数を含むオブジェクト。 たとえば、引数が以下のような場合: ?key1=value1&key2=value2 -> query.key1=value1, query.key2=value2
    urlText実際の HTTPリクエストにおける URL の部分を格納します。 例: GET /status?name=ryan HTTP/1.1 -> url="/status?name=ryan"
    remoteAddressTextクライアントの IPアドレス

    connectionHandler オブジェクト

    WSHandler.onConnection コールバックの結果として、connectionHandler オブジェクトを渡します。これは、WebSocket 接続でイベントが発生するたび (主にメッセージが受信されるたび) に呼び出されるユーザークラスのインスタンスです。 このクラスでは、以下のコールバック関数を定義します (onMessage のみ必須):

    引数説明
    onMessageFunction(必須) この接続から新しいメッセージを受信したときに呼び出される関数
    onOpenFunction4D.WebSocketConnection が作成されたときに呼び出される関数
    onTerminateFunction接続が終了したときに呼び出される関数
    onErrorFunctionエラーが発生したときに呼び出される関数

    connectionHandler.onMessage(ws : 4D.WebSocketConnection ; event : Object)

    引数説明
    ws4D.WebSocketConnection<-カレントの WebSocket 接続オブジェクト
    eventObject<-引数
    typeText"message"
    dataText / Blob / Objectクライアントから送信されたデータ

    WebSocket データ用のコールバックです。 WebSocket がデータを受信するたびに呼び出されます。

    connectionHandler.onOpen(ws : 4D.WebSocketConnection ; event : Object)

    引数説明
    ws4D.WebSocketConnection<-カレントの WebSocket 接続オブジェクト
    eventObject<-引数
    typeText"open"

    connectionHandler オブジェクトが作成されたときに呼び出されます (WSS.onConnection イベントの後)。

    connectionHandler.onTerminate(ws : 4D.WebSocketConnection ; event : Object)

    引数説明
    ws4D.WebSocketConnection<-カレントの WebSocket 接続オブジェクト
    eventObject<-引数
    typeText"terminate"
    codeNumber接続が切断された理由を示すステータスコード。 WebSocket がエラーコードを返さない場合、エラーが発生しなかった場合は code が 1005 に、エラーが発生した場合は 1006 に設定されます。
    reasonText接続が切断された理由を説明するテキスト。 WebSocket が理由を返さない場合、reason は未定義です。

    WebSocket 終了したときに呼び出されます。

    connectionHandler.onError(ws : 4D.WebSocketConnection ; event : Object)

    引数説明
    ws4D.WebSocketConnection<-カレントの WebSocket 接続オブジェクト
    eventObject<-引数
    typeText"error"
    errorsCollection実行エラーの場合、4Dエラースタックのコレクション
  • [].errCode (number) - 4Dエラーコード
  • [].message (text) - 4Dエラーの説明
  • [].componentSignature (text) - エラーを返した内部コンポーネントの署名
  • エラーが発生したときに呼び出されます。

    connectionHandler クラスの例

    この基本的なチャット機能の例では、connectionHandler クラスを使ってメッセージを処理する方法を説明します。

    // myConnectionHandler クラス

    Function onMessage($ws : 4D.WebSocketConnection; $message : Object)
    // すべてのチャットクライアントにメッセージを送信します
    This.broadcast($ws;$message.data)

    Function onOpen($ws : 4D.WebSocketConnection; $message : Object)
    // 新規接続ユーザーにメッセージを送信します
    $ws.send("チャットへようこそ!")
    // その他の接続済チャットクライアントに "新規クライアントが接続しました" メッセージを送信します
    This.broadcast($ws;"新規クライアントが接続しました")

    Function onTerminate($ws : 4D.WebSocketConnection; $message : Object)
    // その他の接続中クライアントに "クライアントが切断されました" メッセージを送信します
    This.broadcast($ws;"クライアント接続が切断されました")

    Function broadcast($ws : 4D.WebSocketConnection; $message:text)
    var $client:4D.WebSocketConnection
    // すべてのチャットクライアントにメッセージを送信します
    For each ($client; $ws.wss.connections)
    // id がカレント接続ではないことを確認します
    If ($client.id#$ws.id)
    $client.send($message)
    End if
    End for each

    options 引数

    任意の options 引数には、以下のプロパティを持つオブジェクトを渡します:

    プロパティ説明デフォルト
    pathTextWebSocketサーバーにアクセスするためのパス。 パスが定義されていない場合、WebSocketサーバーはすべての接続を管理しますundefined
    dataTypeTextconnectionHandler.onMessage で受信するデータ、および WebSocketConnection.send() 関数で送信するデータの型。 値: "text", "blob", "object"。 "object" の場合: (送信) object を json形式に変換して送信します; (受信) json形式を受信して object に変換しますtext

    .connections

    .connections : Collection

    説明

    .connections プロパティは、WebSocketサーバーが処理しているカレントの接続をすべて格納します。 コレクションの各要素が WebSocketConnection オブジェクト です。

    接続が終了すると、このオブジェクトの status は "Closed" に変わり、コレクションから削除されます。

    .dataType

    .dataType : Text

    説明

    .dataType プロパティは、受信または送信されるデータの型を格納します。

    このプロパティは 読み取り専用 です。

    .handler

    .handler : Object

    説明

    .handler プロパティは、WebSocketサーバーの開始に使用された WSSHandler オブジェクトを取得するアクセサーです。

    .path

    .path : Text

    説明

    .path プロパティは、WebSocketサーバーにアクセスするためのパスのパターンです。 パスが定義されなかった場合、WebSocketサーバーはすべての接続を管理します。

    このプロパティは 読み取り専用 です。

    .terminate()

    .terminate()
    .terminate( timeout : Integer )

    引数説明
    timeoutInteger->WebSocketサーバーを終了するまでの待機時間 (秒単位)

    説明

    .terminate() 関数は、WebSocketサーバーを終了します。

    timeout 値が設定されていない場合のデフォルトでは、関数はクローズハンドシェイクを初期化し、相手からクローズフレームを受信するのを待ちます。 その後、FINパケットを送信し、クリーンにソケットを閉じます。 応答を受け取ると、ソケットは破棄されます。

    timeout 値が設定されている場合:

    • 待機時間に達したら強制的にソケットを破棄します。
    • timeout = 0 の場合、クローズフレームや、FINパケットの交換なしで、強制的かつ即座にソケットを破棄します。

    .terminated

    .terminated : Boolean

    説明

    .terminated プロパティは、WebSocketサーバーが終了している場合には true です。

    このプロパティは 読み取り専用 です。