HTTP網絡服務器,框架和客戶端的接口。
有關項目生成器,請參見RAXX.KIT,該項目生成器可幫助您基於RAXX/ACE設置Web項目。
defmodule MyServer do
use Raxx.SimpleServer
@ impl Raxx.SimpleServer
def handle_request ( % { method: :GET , path: [ ] } , _state ) do
response ( :ok )
|> set_header ( "content-type" , "text/plain" )
|> set_body ( "Hello, World!" )
end
def handle_request ( % { method: :GET , path: _ } , _state ) do
response ( :not_found )
|> set_header ( "content-type" , "text/plain" )
|> set_body ( "Oops! Nothing here." )
end
endGET /有[]的請求。 要啟動RAXX服務器,需要兼容的HTTP服務器。此示例使用可以同時服務HTTP/1和HTTP/2的ACE。
raxx_server = { MyServer , nil }
http_options = [ port: 8080 , cleartext: true ]
{ :ok , pid } = Ace.HTTP.Service . start_link ( raxx_server , http_options )handle_request/2回調。在此示例中,它沒有使用,因此將其設置為零。開始您的項目並訪問http:// localhost:8080。
HTTP Exchange涉及客戶將數據發送到接收響應的服務器。一個簡單的視圖是將其建模為以每個方向發送的單個消息。使用此模型對應於Raxx.SimpleServer回調。
request -->
Client ============================================ Server
<-- response當簡單模型不足時,raxx暴露了較低的模型。這包括每個方向的一系列消息。使用此模型對應於Raxx.Server回調。
tail | data(1+) | head(request) -->
Client ============================================ Server
<-- head(response) | data(1+) | tailLongPoll服務器是有狀態的。收到完整的請求後,該服務器必須等待額外的輸入,然後再向客戶端發送響應。
defmodule LongPoll do
use Raxx.Server
@ impl Raxx.Server
def handle_head ( % { method: :GET , path: [ "slow" ] } , state ) do
Process . send_after ( self ( ) , :reply , 30_000 )
{ [ ] , state }
end
@ impl Raxx.Server
def handle_info ( :reply , _state ) do
response ( :ok )
|> set_header ( "content-type" , "text/plain" )
|> set_body ( "Hello, Thanks for waiting." )
end
end[] ;以及服務器的新狀態,在這種情況下沒有變化state 。initial_state 。 SubscribeToMessages服務器服務器流媒體響應。接收請求後,服務器將發送響應的頭部。當數據可用時,數據將作為身體的一部分發送給客戶。聊天室發送a :closed消息時,響應將完成。
defmodule SubscribeToMessages do
use Raxx.Server
@ impl Raxx.Server
def handle_head ( % { method: :GET , path: [ "messages" ] } , state ) do
{ :ok , _ } = ChatRoom . join ( )
outbound = response ( :ok )
|> set_header ( "content-type" , "text/plain" )
|> set_body ( true )
{ [ outbound ] , state }
end
@ impl Raxx.Server
def handle_info ( { ChatRoom , :closed } , state ) do
outbound = tail ( )
{ [ outbound ] , state }
end
def handle_info ( { ChatRoom , data } , state ) do
outbound = data ( data )
{ [ outbound ] , state }
end
endset_body(true)標記響應具有尚不清楚的主體。Upload服務器將數據寫入收到的文件。只有收到完整的請求後才發送回复。
defmodule Upload do
use Raxx.Server
@ impl Raxx.Server
def handle_head ( % { method: :PUT , path: [ "upload" ] body: true } , _state ) do
{ :ok , io_device } = File . open ( "my/path" )
{ [ ] , { :file , device } }
end
@ impl Raxx.Server
def handle_data ( data , state = { :file , device } ) do
IO . write ( device , data )
{ [ ] , state }
end
@ impl Raxx.Server
def handle_tail ( _trailers , state ) do
response ( :see_other )
|> set_header ( "location" , "/" )
end
endhandle_data 。應用程序絕不應該假設如何將身體分解為數據部分。 值得注意的是,傳遞給服務器handle_*功能的請求零件上給出了哪些保證。它取決於服務器類型, Raxx.Server vs Raxx.SimpleServer :
因此,例如,在一個%Raxx.Request{body: false}傳遞給服務器的c:Raxx.Server.handle_head/2回調之後,不會將其他請求零件傳遞給服務器( c:Raxx.Server.handle_info/2消息可能是)。
同樣,這些是從服務器返回的響應部分的有效序列:
任何Raxx.Middleware s都應遵循相同的邏輯。
Raxx.Router可用於將請求與特定服務器模塊匹配。
defmodule MyApp do
use Raxx.Server
use Raxx.Router , [
{ % { method: :GET , path: [ ] } , HomePage } ,
{ % { method: :GET , path: [ "slow" ] } , LongPoll } ,
{ % { method: :GET , path: [ "messages" ] } , SubscribeToMessages } ,
{ % { method: :PUT , path: [ "upload" ] } , Upload } ,
{ _ , NotFoundPage }
]
end