ネットワーク通信

ネットワーク通信は、現在のコンピューティング環境において、かかせない要素となっています。1台のコンピューターのみで出来ることは限られていますが、手元のコンピューターが、別の場所にある他のコンピューターと通信することで、数々の高度な機能が実現されています。例えばオンラインショッピングや、Video Chat 等の機能は、ネットワーク通信無しには実現できません。

Jasmine Tea でのネットワーク通信

Jasmine Tea では、プロジェクト同士がネットワーク通信するための機能を提供します。Jasmine Tea のネットワーク通信では、サーバーとクライアントという2つの役割があります。複数のプロジェクト間でネットワーク接続をするまでの流れは下記のようになります。

  • サーバー側で、bind 関数を使用して、接続の受け付けを開始します。受け付けを開始すると、「接続ID」が割り当てられます。
  • サーバー側で、割り当てられたサーバーの接続IDを取得し、クライアント側に伝えます。
  • クライアント側では、connect 関数を使用して、上記のサーバーに接続します。

接続IDはランダムに見える文字列で、下記のような値を持ちます。

XJQ44JadsglKtwyVJgMF

接続IDはそのプロジェクトの郵便受けのようなものと考えるとわかりやすいかもしれません。他のプロジェクトからは、この接続IDを使用して、接続したりメッセージを送信したりできます。

ひとつのサーバーには、複数のクライアントから接続することができます。クライアントがサーバーに接続すると、お互いにメッセージを送信できるようになります。送信するメッセージは、配列で指定しますので、複数の値を送ることができます。

実際のプログラム例 - 接続する

それでは、実際にネットワーク通信の機能を使ったプログラムを見てみましょう。まずは接続を確立するまでの詳細な手順を説明します。下記はサーバー側で接続の受け付けを始めるためのプログラムです。

port=8080
server_conn_id$=bind$(port)
do
  rem ここにサーバー側での処理を追加していきます。
loop

bind$ 関数に指定するポート番号は、1 - 65535 までの整数を指定します。違うポート番号を使えば複数のサーバーを立ち上げることもできます。bind$ 関数は、指定されたポート番号で、接続の受け付けを開始した後に、結果としてこのサーバーの接続IDを返します。後に receive@ 関数を実行する時に使用するために、この接続IDは server_conn_id$ 変数に記憶させておきます。

最後の do - loop が無いとプログラムはすぐに終了してしまいますので、サーバーとして動作させるにはこのループが必要です。このプログラムを実行すると、プログラム実行画面の右上にひとつアイコンが追加されるはずです。

network-1

このアイコンをクリックすると、下記のような画面が開くはずです。

network-2

コピー用のアイコンをクリックすると、クリップボードにこのサーバーの接続IDがコピーできます。クライアント側のプログラムを作る人に、メッセージアプリなどで、この接続IDを伝えてください。

クライアント側では、下記のようなプログラムで、このサーバーに接続できます。

server_conn_id$="XJQ44JadsglKtwyVJgMF"
client_conn_id$=connect$(server_conn_id$)
if len(client_conn_id$)=0 then
  print "接続に失敗しました"
  end
end if

connect$ 関数は、指定した接続IDを持つサーバーに接続した後に、結果としてクライアント側の接続IDを返します。クライアント側でも、後に receive@ で使用するため、この接続IDを client_conn_id$ 変数に保存しておきます。

実際のプログラム例 - メッセージの送受信

サーバーに接続した後は、send 関数を使用して情報を送信できます。下記の例では、「[["name", "Takashi"], ["age", 50]]」という配列を送信しています。

rem 上記クライアントプログラムの続きです
if not send(server_conn_id$, [["name", "Takashi"], ["age", 50]]) then
  print "送信に失敗しました"
end if

send 関数に渡す1番目の引数は、宛先の接続IDで、2番目の引数は送信したい内容を持つ配列です。send 関数はメッセージの送信に成功すると -1 を、失敗すると 0 を結果として返しますので、その結果をユーザーに伝えることができます。ここでは失敗した時には「送信に失敗しました」と画面に表示して、ユーザーに伝えています。

サーバー側でこの情報を受取るには、receive@ 関数を使用します。下記のプログラムでは、受け取った情報を単純に画面に表示しています。

port=8080
server_conn_id$=bind$(port)
do
  packet@=receive@(server_conn_id$)
  if len(packet@)<>0 then
    client_conn_id$=packet@[0]
    message@=packet@[1]
    print client_conn_id$ + " からメッセージを受信しました"
    print message@
  end if
loop

receive@ 関数には、メッセージを受け取る側の接続IDを指定します。receive@ 関数は、メッセージの受信を試みて、送信済みのメッセージが無ければ空の配列を、送信済みのメッセージがあればその内容を計算結果の配列として返します。この配列は下記のフォーマットを持っています。

[ 送信元の接続ID, 送信された配列 ]

上記のプログラムでは、それぞれの要素を別の変数に記憶させています。

サーバー側からクライアントにメッセージを送りたい場合には、クライアント側の接続IDを使用します。receive@ 関数の結果で得られた配列の1番目の要素がクライアント側の接続IDですので、それを使用することができます。下記は、送信されてきた情報をそっくりそのままクライアントに送り返す Echo サーバーのプログラムです。

port=8080
server_conn_id$=bind$(port)
do
  packet@=receive@(server_conn_id$)
  if len(packet@)<>0 then
    client_conn_id$=packet@[0]
    message@=packet@[1]
    print client_conn_id$ + " からメッセージを受信しました"
    if not send(client_conn_id$, message@) then
      print "送信に失敗しました"
    end if
  end if
loop

サーバー側から、接続されている全てのクライアントにメッセージを送りたい場合には、connected@ 関数を使用して、全てのクライアントの接続IDを取得することができます。下記のプログラムでは接続されている全てのクライアントにメッセージを送信しています。

port=8080
server_conn_id$=bind$(port)
rem ...
rem ...
clients@=connected@(port)
for i=0 to len(clients@)-1
  result=send(clients@[i], ["Hello, client!"])
  if not result then
    print "送信エラー"
  end if
next

実際のプログラム例 - 接続の終了

プログラムを終了する際に、接続は自動的に終了されますので、通常の場合プログラム内で接続を終了する必要はありませんが、もし必要であればサーバー側では unbind 命令を、クライアント側では disconnect 命令を使用して接続を終了できます。

port=8080
server_conn_id$=bind$(port)
unbind port
server_conn_id$="XJQ44JadsglKtwyVJgMF"
client_conn_id$=connect$(server_conn_id$)
disconnect client_conn_id$

ネットワーク通信を使用する際の注意点

複数のブラウザウィンドウで同一プロジェクトを実行した場合、Jasmine Tea のネットワーク機能は予期せぬ動作をする場合があります。なるべく1つのプロジェクトを複数のブラウザウィンドウで同時に実行しないようにしてください。

ネットワーク通信を使用したプログラムのアイデア

ネットワーク通信を使用すれば、Jasmine Tea で色々なことができるようになります。下記のようなプログラムが可能になります。

  • チャットルーム - 複数のユーザーが同じチャットルームに接続して、お互いにメッセージを送信することでチャットができます。
  • 対戦ゲーム - 複数のプロジェクト間で対戦するようなゲームを作ることができます。例えば TicTacToe や、あっち向いてホイなど。
  • ゲームプレイのストリーミング - サーバー側で遊んでいるゲームの画面をそのまま複数のクライアント側でも再現することで、誰かのゲームプレイを見学するといったことも可能です。