Skip to content

Basic Server

Nathan Ferreira edited this page May 6, 2024 · 1 revision

To create an XMPP server you already have practically everything needed, which is (mainly) the Parser.

  1. Listen for incoming connections on the desired port (usually 5222 for XMPP clients)
var server = new Socket(SocketType.Stream, ProtocolType.Tcp);
server.Bind(new IPEndPoint(IPAddress.Any, 5222));
server.Listen(0);
_ = BeginAccept();
  1. After accepting the connection, find a way to manage that connection (the state of the connection)
async Task BeginAccept()
{
	while(true) {
		_ = EndAccept(await server.AcceptAsync());
	}
}

async Task EndAccept(Socket s)
{
	// Create the socket that will read in blocking mode using NetworkStream
	using var stream = new NetworkStream(s, true);
	
	// Creates the parser and provides the stream factory.
	using var parser = new XmppParser(() => stream);
	
	parser.OnStreamStart += async el => 
	{
		// handle incoming <stream:stream> elements
		
		// switch direction from/to, reply back <stream:stream> and reply:
		//  <stream:error> - If an error occurs, either the hostname provided in to="" in stream:stream is invalid or the server does not serve this domain.
		// <stream:features> -  If there is no error. At this point, the server must offer the client which features are supported. Usually the first step is SASL Auth and StartTLS (encryption). After SASL Auth, the server will be requested again for features, and can offer features at the logged-in user level. Usually BIND and SESSION.
	};
	
	parser.OnStreamEnd += async () => 
	{
		// handle incoming </stream:stream> request to close conncetion.
	};
	
	parser.OnStreamElement += async e => 
	{
		// handle all regular elements. (IQ, Message, Presence, Stanzas... etc)
		// All element requests are processed here. It is your responsibility to manage this connection and send responses back to the connection.
	};
	
	try
	{
		// At this point it will "reset" or "start the parser". It will only reset if it has already been created before. any unprocessed XML context will be discarded. Use only in specific cases in accordance with RFC6120
		parser.Reset();
	}
	catch(Exception ex)
	{
		// an error.
		// MUST close the session.
	}
	finally
	{
		// remove from session list
		// handle connection shutdown stuff
	}
}
Clone this wiki locally