私はMessageReceiverは、メッセージがTCP上で受信されるまで待機し、それらを処理し、メインループは、その情報を取得し、それに基づいて行動します2人の労働者エリクシルのワーカープロセス間でデータを共有するにはどうすればよいですか?
worker(Mmoserver.MessageReceiver, []),
worker(Mmoserver.Main, [])
を持っています。 worker1で取得した情報をworker2とどのように共有するのですか?
Mmoserver.ex
これは、これは単なるTCPリスナーを起動します労働者
defmodule Mmoserver do
use Application
def start(_type, _args) do
import Supervisor.Spec, warn: false
IO.puts "Listening for packets..."
children = [
# We will add our children here later
worker(Mmoserver.MessageReceiver, []),
worker(Mmoserver.Main, [])
]
# Start the main supervisor, and restart failed children individually
opts = [strategy: :one_for_one, name: AcmeUdpLogger.Supervisor]
Supervisor.start_link(children, opts)
end
end
MessageReceiver.ex
を開始し、メインファイルです。メインループであるMain.ex
、メッセージを取得し、それは(それのidによって)であるかを把握し、データを解析し、メイン
defmodule Mmoserver.MessageReceiver do
use GenServer
require Logger
def start_link(opts \\ []) do
GenServer.start_link(__MODULE__, :ok, opts)
end
def init (:ok) do
{:ok, _socket} = :gen_udp.open(21337)
end
# Handle UDP data
def handle_info({:udp, _socket, _ip, _port, data}, state) do
parse_packet(data)
# Logger.info "Received a secret message! " <> inspect(message)
{:noreply, state}
end
# Ignore everything else
def handle_info({_, _socket}, state) do
{:noreply, state}
end
def parse_packet(data) do
# Convert data to string, then split all data
# WARNING - SPLIT MAY BE EXPENSIVE
dataString = Kernel.inspect(data)
vars = String.split(dataString, ",")
# Get variables
packetID = Enum.at(vars, 0)
x = Enum.at(vars, 1)
# Do stuff with them
IO.puts "Packet ID:"
IO.puts packetID
IO.puts x
# send data to main
Mmoserver.Main.handle_data(vars)
end
end
に特定の機能に送信することができるはずです。これは、tcpリスナーによって受信された最新のすべてのデータを処理し、それを処理します。最終的にゲームの状態も更新されます。
defmodule Mmoserver.Main do
use GenServer
@tickDelay 33
def start_link(opts \\ []) do
GenServer.start_link(__MODULE__, [], name: Main)
end
def init (state) do
IO.puts "Main Server Loop started..."
# start the main loop, parameter is the initial tick value
mainLoop(0)
# return, why 1??
{:ok, 1}
end
def handle_data(data) do
GenServer.cast(:main, {:handle_data, data})
end
def handle_info({:handle_data, data}, state) do
# my_function(data)
IO.puts "Got here2"
IO.puts inspect(data)
{:noreply, state}
end
# calls respective game functions
def mainLoop(-1) do
IO.inspect "Server Loop has ended!" # base case, end of loop
end
def mainLoop(times) do
# do shit
# IO.inspect(times) # operation, or body of for loop
# sleep
:timer.sleep(@tickDelay);
# continue the loop RECURSIVELY
mainLoop(times + 1)
end
end
可能性として 'GenStage'を調べることに言及する価値があるかもしれません。 –
これはうまくいくようですが、最初に呼び出されない限りudpリスナーは機能しません。これはおそらく、Mainが壊れないループを開始するという事実と関係があります。私はそれらを持っていた順番にコールを入れ、udpリスナは動作し、メッセージがhandle_dataを通ってきたときにはcallendがhandle_infoではない。なぜ、私はちょうど今私のポストにコードを入れて – Diericx
それは私が非同期であるために両方のプロセスが必要なので、メインは、TCPリスナーをブロックしていることを私も心配。 – Diericx