Netly
v3.1.0
활발한 개발은 'dev' 브랜치에서 이루어집니다. 안정 릴리스에 대해서는 'main' 브랜치를 참조하세요.
Netly 버전 4가 곧 출시될 예정이며, 이는 Netly와 상호 작용하는 새로운 방식을 검증하는 데 도움이 됩니다. 자세히 보기
Netly의 귀하의 별은 우리의 여정을 밝게 하고 실질적인 영향을 미칩니다! |
버전 4 개발 로드맵
완전히 구현됨 | 바이트 3 • TCP 클라이언트 • TCP 서버 • UDP 클라이언트 • UDP 서버 • HTTP 클라이언트 • HTTP 서버 • HTTP WebSocket • RUDP 클라이언트 • RUDP 서버 |
---|---|
진행 중인 작업 | 문서 v4 #63(새 문서 웹사이트) HTTP Body(Enctype Detector 및 Parser) #67(미들웨어로서의 Body Parser) |
보류 중인 기능 | Byter v4 추가 *개발 중 RUDP 테스트 추가 HTTP 테스트 추가 Websocket 테스트 추가 |
Netly라는 프로젝트에 대한 기본 정보를 얻으세요.
개요 | Netly는 네트워크 통신을 간소화하도록 설계된 강력한 C# 소켓 라이브러리입니다. HTTP, TCP, SSL/TLS, UDP, Reliable UDP(RUDP) 및 WebSocket을 포함한 여러 프로토콜에 대한 포괄적인 지원을 제공합니다. 이러한 다재다능함 덕분에 Netly는 멀티플레이어 게임과 채팅 시스템부터 실시간 데이터 교환에 이르기까지 광범위한 응용 프로그램을 개발하는 데 탁월한 선택이 됩니다. |
---|---|
웹사이트 | 저장소: github.com/alec1o/netly 문서: netly.docs.kezero.com |
스폰서 | |
서포터 | Netly에 기여하는 이유는 무엇입니까?
|
공식 출판사
너겟 | 유니티 에셋 스토어 |
---|---|
너겟에 설치 | 에셋 스토어에 설치 |
주목할만한 변화
v1.xx | v2.xx | v3.xx | v4.xx |
---|---|---|---|
유산 | 유산 | 안정적인 | 개발 |
TCP 지원 | 메시지 프레이밍을 지원하는 TCP | TLS/SSL을 지원하는 TCP | HTTP 클라이언트 및 서버 지원 |
UDP 지원 | TCP 및 UDP 성능 향상 | 연결이 있는 UDP(시간 초과 응답) | 안정적인 UDP(RUDP) 클라이언트 및 서버 지원 |
새로운 메시지 프레이밍 프로토콜 및 성능 향상 | WebSocket 클라이언트 및 서버 지원 | ||
바이터 2.0으로 업그레이드 | 바이터 3.0으로 업그레이드 | ||
문서화 프레임워크로서의 Docsify | Docusaurus 및 DocFxMarkdownGen을 통한 문서 개선 | ||
구문 및 내부 개선 | |||
XML 주석 개선 |
통합에 대한 기술 설명
테스트된 플랫폼 목록 |
|
---|---|
종속성 | 바이터 |
짓다 |
# 1. clone project
$ git clone "https://github.com/alec1o/Netly" netly
# 2. build project
$ dotnet build "netly/" - c Release - o "netly/bin/"
# NOTE:
# Netly.dll require Byter.dll because is Netly dependency
# Netly.dll and Byter.dll have on build folder <netly-path>/bin/ |
특징 |
|
코드 하이라이트
TCP | 고객 using Netly ;
TCP . Client client = new TCP . Client ( framing : true ) ; client . On . Open ( ( ) =>
{
printf ( "connection opened" ) ;
} ) ;
client . On . Close ( ( ) =>
{
printf ( "connetion closed" ) ;
} ) ;
client . On . Error ( ( exception ) =>
{
printf ( "connection erro on open" ) ;
} ) ;
client . On . Data ( ( bytes ) =>
{
printf ( "connection receive a raw data" ) ;
} ) ;
client . On . Event ( ( name , data ) =>
{
printf ( "connection receive a event" ) ;
} ) ;
client . On . Modify ( ( socket ) =>
{
printf ( "called before try open connection." ) ;
} ) ;
client . On . Encryption ( ( certificate , chain , errors ) =>
{
// Only if client.IsEncrypted is enabled
printf ( "validate ssl/tls certificate" ) ;
// return true if certificate is valid
return true ;
} ) ; // open connection if closed
client . To . Open ( new Host ( "127.0.0.1" , 8080 ) ) ;
// close connection if opened
client . To . Close ( ) ;
// send raw data if connected
client . To . Data ( new byte [ 2 ] { 128 , 255 } ) ;
client . To . Data ( "hello world" , NE . Encoding . UTF8 ) ;
// send event if connected
client . To . Event ( "name" , new byte [ 2 ] { 128 , 255 } ) ;
client . To . Event ( "name" , "hello world" , NE . Encoding . UTF8 ) ;
// enable encryption (must call before client.To.Open)
client . To . Encryption ( true ) ; 섬기는 사람 using Netly ;
TCP . Server server = new TCP . Server ( framing : true ) ; server . On . Open ( ( ) =>
{
printf ( "connection opened" ) ;
} ) ;
server . On . Close ( ( ) =>
{
printf ( "connection closed" ) ;
} ) ;
server . On . Error ( ( exception ) =>
{
printf ( "connection error on open" ) ;
} ) ;
server . On . Accept ( ( client ) =>
{
client . On . Modify ( ( socket ) =>
{
printf ( "modify client socket e.g Enable NoDelay" ) ;
} ) ;
client . On . Open ( ( ) =>
{
printf ( "client connected" ) ;
} ) ;
client . On . Data ( ( bytes ) =>
{
printf ( "client receive a raw data" ) ;
} ) ;
client . On . Event ( ( name , bytes ) =>
{
printf ( "client receive a event" ) ;
} ) ;
client . On . Close ( ( ) =>
{
printf ( "client disconnected" ) ;
} ) ;
} ) ;
server . On . Modify ( ( socket ) =>
{
printf ( "called before try open connection." ) ;
} ) ; // open connection
server . To . Open ( new Host ( "1.1.1.1" , 1111 ) ) ;
// close connection
server . To . Close ( ) ;
// enable encryption support (must called before server.To.Open)
server . To . Encryption ( enable : true , @mypfx , @mypfxpassword , SslProtocols . Tls12 ) ;
// broadcast raw data for all connected client
server . To . DataBroadcast ( "text buffer" ) ;
server . To . DataBroadcast ( new byte [ ] { 1 , 2 , 3 } ) ;
// broadcast event (netly event) for all connected client
server . To . EventBroadcast ( "event name" , "text buffer" ) ;
server . To . EventBroadcast ( "event name" , new byte [ ] { 1 , 2 , 3 } ) ; |
---|---|
UDP | 고객 using Netly ;
UDP . Client client = new UDP . Client ( ) ; client . On . Open ( ( ) =>
{
printf ( "connection opened" ) ;
} ) ;
client . On . Close ( ( ) =>
{
printf ( "connection closed" ) ;
} ) ;
client . On . Error ( ( exception ) =>
{
printf ( "connection error on open" ) ;
} ) ;
client . On . Data ( ( bytes ) =>
{
printf ( "connection received a raw data" ) ;
} ) ;
client . On . Event ( ( name , eventBytes ) =>
{
printf ( "connection received a event" ) ;
} ) ;
client . On . Modify ( ( socket ) =>
{
printf ( "called before try open connection." ) ;
} ) ; // open connection if closed
client . To . Open ( new Host ( "127.0.0.1" , 8080 ) ) ;
// close connection if opened
client . To . Close ( ) ;
// send raw data if connected
client . To . Data ( new byte [ 2 ] { 128 , 255 } ) ;
client . To . Data ( "hello world" , NE . Encoding . UTF8 ) ;
// send event if connected
client . To . Event ( "name" , new byte [ 2 ] { 128 , 255 } ) ;
client . To . Event ( "name" , "hello world" , NE . Encoding . UTF8 ) ; 섬기는 사람 using Netly ;
UDP . Server server = new UDP . Server ( ) ; server . On . Open ( ( ) =>
{
printf ( "connection opened" ) ;
} ) ;
server . On . Close ( ( ) =>
{
printf ( "connection closed" ) ;
} ) ;
server . On . Error ( ( exception ) =>
{
printf ( "connection error on open" ) ;
} ) ;
server . On . Accept ( ( client ) =>
{
client . On . Open ( ( ) =>
{
printf ( "client connected" ) ;
} ) ;
client . On . Close ( ( ) =>
{
// Only if use connection is enabled.
printf ( "client disconnected" ) ;
} ) ;
client . On . Data ( ( bytes ) =>
{
printf ( "client received a raw data" ) ;
} ) ;
client . On . Event ( ( name , bytes ) =>
{
printf ( "client received a event" ) ;
} ) ;
} ) ; // open connection
server . To . Open ( new Host ( "127.0.0.1" , 8080 ) ) ;
// close connection
server . To . Close ( ) ;
// broadcast raw data for all connected client
server . To . DataBroadcast ( "text buffer" ) ;
server . To . DataBroadcast ( new byte [ ] { 1 , 2 , 3 } ) ;
// broadcast event (netly event) for all connected client
server . To . EventBroadcast ( "event name" , "text buffer" ) ;
server . To . EventBroadcast ( "event name" , new byte [ ] { 1 , 2 , 3 } ) ;
|
HTTP | 고객 using Netly ;
HTTP . Client client = new HTTP . Client ( ) ;
// add http header for request
client . Headers . Add ( "Content-Type" , "json" ) ;
client . Headers . Add ( "Token" , "ImGui.h" ) ;
// add http url queries e.g: https://www.alec1o.com/?page=about&version=4
client . Queries . Add ( "page" , "about" ) ;
client . Queries . Add ( "version" , "4" ) ;
// set request timeout (ms) default 15s (15000ms), 0 or negative value means infinite timeout.
client . Timeout = 6000 ; // 6s
// is opened: while is requesting
bool isFetching = client . IsOpened ; HttpClient http = null ;
// called before try connect to server
// modify the HttpClient object
client . On . Modify ( ( HttpClient instance ) =>
{
http = instance ;
} ) ;
// connection is opened and fetch server.
client . On . Open ( ( response ) =>
{
// you can use "http" instance on this scope (isn't null)
if ( http . < foo > == < bar > ) { .. . }
} ) ;
// erro on fetch, it can be timeout or whatever error
// but if you receives error it mean the operation is called or done
client . On . Error ( ( Exception exception ) =>
{
Ny . Logger . PushError ( exception ) ;
} ) ;
// connection is closed with fetch server.
client . On . Close ( ( ) =>
{
if ( http . < bar > == < foo > ) { .. . }
} ) ; // used to fetch a server
client . To . Open ( "method e.g GET" , "url" , "body, allow null" ) ;
// used for cancel opened request
client . To . Close ( ) ; 섬기는 사람 using Netly ;
HTTP . Server server = new HTTP . Server ( ) ;
// return true if server is serve http context
bool isServe = server . IsOpened ; server . On . Open ( ( ) =>
{
// http server opened
} ) ;
server . On . Close ( ( ) =>
{
// http server closed
} ) ;
server . On . Error ( ( exception ) =>
{
// http server open error
} ) ;
server . On . Modify ( ( httpListener ) =>
{
// HttpListener instance, called before try open connection.
} ) ;
// Open http server connection
server . To . Open ( new Uri ( "http://127.0.0.1:8080/" ) ) ;
// Close http server connection
server . To . Close ( ) ; 지도 // Map path
server . Map . Get ( "/" , async ( req , res ) => {
// Handle async: GET
} )
server . Map . Post ( "/user" , ( req , res ) => {
// Handle sync: POST
} ) ;
// map using dynamic URL
server . Map . Delete ( "/post/{userId}/group/{groupId}" , async ( req , res ) ) =>
{
string userId = req . Param [ "userId" ] ;
string groupId = req . Param [ "groupId" ] ;
// Handle async: Delete from dynamic URL path
} ) ;
server . Map . WebSocket ( "/echo" , ( req , ws ) =>
{
// Handle websocket connection from path
} ) ;
/*
You can map:
* Get # get request
* Post # post request
* Delete # delete request
* Put # put request
* Patch # patch request
* Trace # trace request
* Options # options request
* Head # head request, (only head)
* All # all http nethod request
* WebSocket # websocket request
*/
미들웨어 /*
Note: Middlewares is executed in added order
*/
// Global Middleware (*don't have workflow path)
server . Middleware . Add ( async ( req , res , next ) => {
// verify request timer
Stopwatch watch = new Stopwatch ( ) ; // init timer
next ( ) ; // call another middleware.
watch . Stop ( ) ; // stop timer
res . Header . Add ( "Request-Timer" , watch . ElapsedMilliseconds . ToString ( ) ) ;
} ) ;
// Local middleware (have workflow path)
server . Middleware . Add ( "/admin" , async ( req , res , next ) => {
if ( MyApp . CheckAdminByHeader ( req . Header ) )
{
res . Header . Add ( "Admin-Token" , MyApp . RefreshAdminHeaderToken ( req ) ) ;
// call next middleware
next ( ) ;
// now. all middleware is executed. (because this is two way middleware)
res . Header . Add ( "Request-Delay" , ( DateTime . UtcNow - timer ) ( ) ) ;
}
else
{
res . Header . Add ( "Content-Type" , "application/json;charset=UTF-8" ) ;
await res . Send ( 404 , "{ 'error': 'invalid request.' }" ) ;
// skip other middlewares:
// next();
}
} ) ; |
루드프 | 고객 using Netly ;
RUDP . Client client = new RUDP . Client ( ) ; client . On . Open ( ( ) =>
{
printf ( "connection opened" ) ;
} ) ;
client . On . Close ( ( ) =>
{
printf ( "connection closed" ) ;
} ) ;
client . On . Error ( ( exception ) =>
{
printf ( "connection error on open" ) ;
} ) ;
client . On . Data ( ( bytes , type ) =>
{
printf ( "connection received a raw data" ) ;
} ) ;
client . On . Event ( ( name , bytes , type ) =>
{
printf ( "connection received a event" ) ;
} ) ;
client . On . Modify ( ( socket ) =>
{
printf ( "called before try open connection." ) ;
} ) ; // open connection if closed
client . To . Open ( new Host ( "127.0.0.1" , 8080 ) ) ;
// close connection if opened
client . To . Close ( ) ;
// send raw data if connected
client . To . Data ( new byte [ 2 ] { 128 , 255 } , RUDP . Unreliable ) ;
client . To . Data ( "hello world" , NE . Encoding . UTF8 , RUDP . Reliable ) ;
// send event if connected
client . To . Event ( "name" , new byte [ 2 ] { 128 , 255 } , RUDP . Unreliable ) ;
client . To . Event ( "name" , "hello world" , NE . Encoding . UTF8 , RUDP . Reliable ) ; 섬기는 사람 using Netly ;
RUDP . Server server = new RUDP . Server ( ) ; server . On . Open ( ( ) =>
{
printf ( "connection opened" ) ;
} ) ;
server . On . Close ( ( ) =>
{
printf ( "connection closed" ) ;
} ) ;
server . On . Error ( ( exception ) =>
{
printf ( "connection error on open" ) ;
} ) ;
server . On . Accept ( ( client ) =>
{
client . On . Open ( ( ) =>
{
printf ( "client connected" ) ;
} ) ;
client . On . Close ( ( ) =>
{
// Only if use connection is enabled.
printf ( "client disconnected" ) ;
} ) ;
client . On . Data ( ( bytes , type ) =>
{
if ( type == RUDP . Reliable ) { .. . }
else if ( type == RUDP . Unreliable ) { .. . }
else { .. . } /* type == RUDP.Sequenced */
printf ( "client received a raw data" ) ;
} ) ;
client . On . Event ( ( name , type ) =>
if ( type == RUDP . Reliable ) { .. . }
else if ( type == RUDP . Unreliable ) { .. . }
else { .. . } /* type == RUDP.Sequenced */
printf ( "client received a event" ) ;
} ) ;
} ) ; // open connection
server . To . Open ( new Host ( "127.0.0.1" , 8080 ) ) ;
// close connection
server . To . Close ( ) ;
// broadcast raw data for all connected client
server . To . DataBroadcast ( "text buffer" , RUDP . Unreliable ) ;
server . To . DataBroadcast ( new byte [ ] { 1 , 2 , 3 } , RUDP . Reliable ) ;
server . To . DataBroadcast ( new byte [ ] { 3 , 2 , 1 } , RUDP . Sequenced ) ;
// broadcast event (netly event) for all connected client
server . To . EventBroadcast ( "event name" , "text buffer" , RUDP . Unreliable ) ;
server . To . EventBroadcast ( "event name" , new byte [ ] { 1 , 2 , 3 } , RUDP . Reliable ) ;
server . To . EventBroadcast ( "event name" , new byte [ ] { 3 , 2 , 1 } , RUDP . Sequenced ) ; |
웹소켓 | 고객 using Netly ;
HTTP . WebSocket client = new HTTP . WebSocket ( ) ; client . On . Open ( ( ) =>
{
// websocket connection opened
} ) ;
client . On . Close ( ( ) =>
{
// websocket connection closed
} ) ;
client . On . Error ( ( exception ) =>
{
// error on open websocket connectin
} ) ;
client . On . Data ( ( bytes , type ) =>
{
if ( type == HTTP . Binary ) { .. . }
else if ( type == HTTP . Text ) { .. . }
else { /* NOTE: it's imposible */ }
// raw data received from server
} ) ;
client . On . Event ( ( name , bytes , type ) =>
{
if ( type == HTTP . Binary ) { .. . }
else if ( type == HTTP . Text ) { .. . }
else { /* NOTE: it's imposible */ }
// event received from server
} ) ;
client . On . Modify ( ( wsSocket ) =>
{
// modify websocket socket
} ) ; // open websocket client connection
client . To . Open ( new Uri ( "ws://127.0.0.1:8080/echo" ) ) ;
// close websocket client connection
client . To . Close ( ) ;
// send raw data for server
// text message
client . To . Data ( "my message" , HTTP . Text ) ;
// binnary message
client . To . Data ( NE . GetBytes ( "my buffer" ) , HTTP . Binary ) ;
// send event (netly event) for server
// text message
client . To . Event ( "event name" , "my message" , HTTP . Text ) ;
// binnary message
client . To . Data ( "event name" , NE . GetBytes ( "my buffer" ) , HTTP . Binary ) ; 섬기는 사람 using Netly ;
using Netly . Interfaces ;
HTTP . Server server = new HTTP . Server ( ) ;
IHTTP . WebSocket [ ] Clients = server . WebSocketClients ; server . Map . WebSocket ( "/chat/{token}" , async ( req , ws ) =>
{
// Accept websocket from dynamic path
string token = req . Params [ "token" ] ;
// validate websocket connection from params
if ( Foo . Bar ( token ) == false )
{
ws . To . Close ( ) ;
}
ws . On . Modify ( .. . ) ;
ws . On . Open ( .. . ) ;
ws . On . Close ( .. . ) ;
ws . On . Data ( .. . ) ;
ws . On . Event ( .. . ) ;
} ) ;
server . Map . Websocket ( "/echo" , ( req , ws ) =>
{
// Handle websocket on /echo path
ws . On . Modify ( ( wsSocket ) =>
{
// modify server-side websocket ocket
} ) ;
ws . On . Open ( ( ) =>
{
// server-side websocket connection opened
} ) ;
ws . On . Close ( ( ) =>
{
// server-side websocket connection closed
} ) ;
ws . On . Data ( ( bytes , type ) =>
{
if ( type == HTTP . Binary ) { .. . }
else if ( type == HTTP . Text ) { .. . }
else { /* NOTE: it's imposible */ }
// server-side websocket received raw data
} ) ;
ws . On . Event ( ( name , bytes , type ) =>
{
if ( type == HTTP . Binary ) { .. . }
else if ( type == HTTP . Text ) { .. . }
else { /* NOTE: it's imposible */ }
// server-side websocket received event
} ) ;
} ) ; server . On . Open ( ( ) =>
{
// http server opened
} ) ;
server . On . Close ( ( ) =>
{
// http server closed
} ) ;
server . On . Error ( ( exception ) =>
{
// http server open error
} ) ;
server . On . Modify ( ( httpListener ) =>
{
// HttpListener instance, called before try open connection.
} ) ;
// Open http server connection
server . To . Open ( new Uri ( "http://127.0.0.1:8080/" ) ) ;
// Close http server connection
server . To . Close ( ) ; // open websocket client connection
server . To . Open ( new Uri ( "ws://127.0.0.1:8080/echo" ) ) ;
// close websocket client connection
server . To . Close ( ) ;
// broadcast raw data for all connected websocket socket
// text message
server . To . WebsocketDataBroadcast ( "my message" , HTTP . Text ) ;
// binnary message
server . To . WebsocketDataBroadcast ( NE . GetBytes ( "my buffer" ) , HTTP . Binary ) ;
// broadcast event (netly event) for all connected websocket socket
// text message
server . To . WebsocketEventBroadcast ( "event name" , "my message" , HTTP . Text ) ;
// binnary message
server . To . WebsocketEventBroadcast ( "event name" , NE . GetBytes ( "my buffer" ) , HTTP . Binary ) ; |
바이터 | 자세한 내용 및 자세한 내용은 Byter의 공식 정보를 참조하세요.
원어 using Byter ;
경고 프리미티브는 복잡한 데이터(예: T[], List, Class, Struct, Enum)를 직렬화/역직렬화할 수 있습니다.
예
확대 using Byter ;
|
통합 및 상호작용 예시 코드
기준 | 콘솔 using System ;
using Netly ;
public class Program
{
private static void Main ( string [ ] args )
{
UDP . Client client = new UDP . Client ( ) ;
client . On . Open ( ( ) =>
{
Console . WriteLine ( < some - text - here > ) ;
} ;
client . On . Close ( ( ) =>
{
Console . WriteLine ( < some - text - here > ) ;
} ;
client . On . Error ( ( exception ) =>
{
Console . WriteLine ( < some - text - here > ) ;
} ;
while ( true )
{
if ( ! client . IsOpened )
{
client . To . Open ( new Host ( "1.1.1.1" , 1111 ) ) ;
}
else
{
Console . WriteLine ( "Message: " ) ;
string message = Console . ReadLine ( ) ;
client . To . Data ( message ?? "No message." , NE . Encoding . UTF8 ) ;
}
}
}
} |
---|---|
아마 엔진 | 스크립트 using System ;
using FlaxEngine ;
using Netly ;
public class Example : Script
{
public string message ;
internal UDP . Client client ;
public override void Awake ( )
{
client = new UDP . Client ( ) ;
client . On . Open ( ( ) =>
{
Debug . Log ( < some - text - here > ) ;
} ;
client . On . Close ( ( ) =>
{
Debug . Log ( < some - text - here > ) ;
} ;
client . On . Error ( ( exception ) =>
{
Debug . Log ( < some - text - here > ) ;
} ;
}
public override void Start ( )
{
client . To . Open ( new Host ( "1.1.1.1" , 1111 ) ) ;
}
public override void Update ( )
{
if ( ! client . IsOpened )
{
client . To . Open ( new Host ( "1.1.1.1" , 1111 ) ) ;
}
else
{
if ( Input . GetKeyDown ( KeyCode . Space ) )
{
client . To . Data ( message ?? "No message." , NE . Encoding . UTF8 ) ;
}
}
}
} |
유니티 엔진 | 모노행동 using System ;
using FlaxEngine ;
using Netly ;
public class Example : MonoBehaviour
{
public string message ;
internal UDP . Client client ;
private void Awake ( )
{
client = new UDP . Client ( ) ;
client . On . Open ( ( ) =>
{
Debug . Log ( < some - text - here > ) ;
} ;
client . On . Close ( ( ) =>
{
Debug . Log ( < some - text - here > ) ;
} ;
client . On . Error ( ( exception ) =>
{
Debug . Log ( < some - text - here > ) ;
} ;
}
private void Start ( )
{
client . To . Open ( new Host ( "1.1.1.1" , 1111 ) ) ;
}
private void Update ( )
{
if ( ! client . IsOpened )
{
client . To . Open ( new Host ( "1.1.1.1" , 1111 ) ) ;
}
else
{
if ( Input . GetKeyDown ( KeyCode . Space ) )
{
client . To . Data ( message ?? "No message." , NE . Encoding . UTF8 ) ;
}
}
}
} |
경고: | 루프가 아닌 이벤트 핸들러를 한 번 초기화합니다 . `Awake()` 또는 `Start()`와 같은 초기화 메서드에서 `..On.` 메서드를 사용하여 핸들러를 설정합니다. 성능을 유지하려면 업데이트 루프에서 이러한 설정을 반복적으로 설정하지 마세요. 프로토콜 작업을 현명하게 처리하십시오 . `..To.Open()`, `..To.Data()`, `..To.Close()`와 같은 `..To.` 메서드를 신중하게 관리하여 사용하세요. 아직 열려 있지 않은 경우에만 연결을 열고 연결이 활성화된 것으로 확인된 경우에만 데이터를 보내도록 하세요. 긴밀한 루프에서 이러한 메서드를 호출하지 마세요. // OK 100% Recommended
private void Start ( )
{
var client = .. . ;
client . On . Open ( ( ) => .. . ) ; // e.g generic handler
client . On . Open ( ( ) => .. . ) ; // e.g only to send "Hi"
client . On . Event ( ( name , bytes , ? ) => .. . ) ; // e.g generic event handler
client . On . Event ( ( name , bytes , ? ) => .. . ) ; // e.g only to handle A event
client . On . Event ( ( name , bytes , ? ) => .. . ) ; // e.g only to handle B event
client . To . Open ( .. . ) ;
} public void Update ( )
{
client . To . Open ( .. . ) ; // [OK? - May Not In Loop?]
client . To . Data ( .. . ) ; // [OK? - May Not In Loop?]
client . To . Event ( .. . ) ; // [OK? - May Not In Loop?]
client . To . Close ( .. . ) ; // [OK? - May Not In Loop?]
ws . On . Open ( ( ) => .. . ) ; // [BAD - Never In Loop]
ws . On . Close ( ( ) => .. . ) ; // [BAD - Never In Loop]
ws . On . Data ( ( bytes ) => .. . ) ; // [BAD - Never In Loop]
ws . On . Error ( ( exception ) => .. . ) ; // [BAD - Never In Loop]
ws . On . Event ( ( name , bytes ) => .. . ) ; // [BAD - Never In Loop]
} |