Skip to Content

WebSocketアクション

WebSocketアクションは、WebSocketのサーバーに接続し、ステップに並べた順にメッセージを送受信して、受け取ったものを返します。

外部アクションとしてmozership/probe-websocket で公開しています。ワークフローが初めて使うときにProbeがダウンロードし、固定したコミットのaction.ymlが示すSHA-256と一致する実行ファイルだけを実行します。Probe v1.17.0以降が必要です。ガードの下で実行するには、またprobe checkでwithを検査するには、v1.21.0以降が必要です。

基本的な構文

ステップでは40文字のコミットSHAでアクションを固定します。各リリース のノートの先頭に、コピーして使うusesの行があります。

steps: - name: Subscribe and get an update uses: github.com/mozership/probe-websocket@a159244b9ab3f5ec4c61782af1e711bce705c8a8 # v0.1.0 with: url: wss://stream.example.com/ws headers: Authorization: "Bearer {{vars.token}}" messages: - send: {type: subscribe, channel: ticker} - receive: match: {type: subscribed} - receive: count: 3 match: {type: update} test: res.code == 101 && len(res.messages) == 4 && res.messages[3].data.price > 0

ステップごとに新しく接続し、messagesを順に実行してから閉じます。購読は次のステップに引き継がれないため、一連のやり取りは1つのステップにまとめます。

パラメータ

パラメータ型必須デフォルト説明
urlStringはい-接続先のサーバー。wsまたはwss
headersObjectいいえ-Authorizationなどのハンドシェイクのリクエストヘッダー。User-Agent: probe-websocket/<version>を上書きします
subprotocolsListいいえ-提示するサブプロトコル。優先する順に並べます
messagesListいいえ-送受信する内容を順に並べたもの。メッセージを参照してください。省略すると、接続して閉じるだけです
timeoutDurationいいえ30sハンドシェイクから切断までのステップ全体の制限時間。10sのような形式か秒数で指定します。0を指定すると制限しません

これら以外のキーをwithに書くと、何も送る前にステップが失敗します。action.ymlはこれらをparamsとして申告しているため、probe checkがそのキーを行番号とともに報告します。

メッセージ

messagesの各エントリには、次のキーのうちちょうど1つを書きます。

キー値動作
send文字列、またはそれ以外の値テキストメッセージを送ります。文字列はそのまま、それ以外の値はJSONにして送ります
send_binaryBase64の文字列デコードしたバイト列をバイナリメッセージとして送ります
receiveObject、または空メッセージを待ち、res.messagesに入れます。オプションがなければ次の1通を受け取ります

receiveには次のオプションがあります。

オプション型説明
countInteger受け取るメッセージの数。既定は1
until_closeBooleanサーバーが接続を閉じるまで、すべてのメッセージを受け取ります。countとは併用できず、最後のエントリにしか書けません
matchAnydataがこの値を含むメッセージだけを受け取り、それ以外は読み飛ばします。Objectは、そのすべてのキーを一致する値とともに持つObjectに一致します。リストは、同じ数の要素がそれぞれ一致するリストに一致します。それ以外の値は等しい値に一致し、数値は値で比べます

matchがあるとき、countは一致したメッセージの数です。読み飛ばしたメッセージは残しません。

レスポンスオブジェクト

プロパティ型説明
res.codeIntegerハンドシェイクのHTTPステータスコード。接続がアップグレードされたときは101
res.statusString"101 Switching Protocols"のようなHTTPステータス行
res.headersObject正規化した名前をキーとするハンドシェイクのレスポンスヘッダー
res.subprotocolStringサーバーが選んだサブプロトコル。選ばなかったときは空
res.messagesArrayreceiveのエントリが受け取ったメッセージ。受け取った順に並びます
res.closeObjectサーバーが接続を閉じたときのcodeとreason。閉じなかったときはnull
res.errorString最後のエントリより前でメッセージの処理が止まった理由。すべてのエントリを終えたときは空
reqObject使ったurl、headers、subprotocols、messages
rtDurationハンドシェイクから切断までの時間
statusInteger接続がアップグレードされ、すべてのエントリを終えたら0。それ以外は1

res.messagesの各メッセージには、次のプロパティがあります。

プロパティ型説明
typeString"text"または"binary"
dataAnyテキストメッセージは、JSONなら解析した値、それ以外は文字列。バイナリメッセージはBase64
rawString解析前のテキスト、またはバイナリメッセージのBase64

サーバーがハンドシェイクに応答した後のことは、すべて結果として扱います。そのため、401で拒否されたハンドシェイク、期待したメッセージより前の切断、届かなかったメッセージもテストで確かめられます。メッセージの処理は実行できない最初のエントリで止まり、res.errorがそのエントリを示します。たとえばmessages[1] took 2 of 3 messages: timed out after 10sのようになります。接続の拒否やタイムアウトのように、ハンドシェイクに応答を得られなかったときだけ、ステップをエラーとして失敗させます。

すべてのエントリを終えた時点でサーバーが接続を閉じていなければ、アクションが1000で閉じます。16 MiBを超えるメッセージを受け取ると、やり取りはそこで終わります。

steps: - name: The feed sends two updates, then closes uses: github.com/mozership/probe-websocket@a159244b9ab3f5ec4c61782af1e711bce705c8a8 # v0.1.0 with: url: wss://stream.example.com/replay messages: - receive: until_close: true match: {type: update} test: len(res.messages) == 2 && res.close.code == 1000

ガードの下での動作

このアクションは実行のガードを守り、action.ymlでguard: [read-only, allow-host]を申告しています。そのため、どちらのガードの下でも--allow-actionなしで実行します。拒否したステップは、接続する前に種類refusedで失敗します。

  • --read-onlyの下では、受信だけのステップを実行します。メッセージがサーバーで何をするかは判断できないため、sendかsend_binaryのエントリを含むステップは拒否します。購読の申し込みのように、何かを送らないとメッセージを返さないサーバーには、--allow-actionで許可が必要です。
  • --allow-hostの下では、urlのホストと、ハンドシェイクの各リダイレクト先のホストが、実行が許可するものでなければなりません。ポートのないURLは、スキームの既定のポート(wsは80、wssは443)として扱います。

ガードを参照してください。

関連項目

  • 外部アクション - Probeが外部アクションを解決し、照合する仕組み
  • HTTP - 通常のHTTPリクエスト
  • GraphQL - HTTPでのGraphQLのクエリ
更新日時