| 
 | 
 | 
 
Home » U++ Library support » U++ Core » How to close  the websocket connection 
	| 
		
 |  
	| 
		
 |  
	| 
		
 |  
	| 
		
 |  
	
		
		
			| Re: How to close  the websocket connection [message #49459 is a reply to message #48944] | 
			Wed, 14 February 2018 19:17    | 
		 
		
			
				
				
				
					
						  
						uppjj
						 Messages: 9 Registered: February 2018  Location: France
						
					 | 
					Promising Member  | 
					 | 
		 
		 
	 | 
 
	
		Hello 
I got the same problem, "Close" put my websocket client in infinite loop. 
Server receives the "Close" message from the client but does not actually send the response, because it is in non-blocking mode.  
I just do this change in uppsrc/core/WebSocket.cpp , function "out": 
 
// while(IsBlocking()  && socket->IsOpen() && !IsError() && out_queue.GetCount())
   while((IsBlocking() || (s[0] == CLOSE))  && socket->IsOpen() && !IsError() && out_queue.GetCount())
  
 
and got "Close" working well...
		
		
		[Updated on: Wed, 14 February 2018 21:10] by Moderator Report message to a moderator  
 |  
	| 
		
	 | 
 
 
 |  
	| 
		
 |  
	
		
		
			| Re: How to close  the websocket connection [message #49528 is a reply to message #49487] | 
			Sat, 24 February 2018 15:59    | 
		 
		
			
				
				
				
					
						  
						uppjj
						 Messages: 9 Registered: February 2018  Location: France
						
					 | 
					Promising Member  | 
					 | 
		 
		 
	 | 
 
	
		thanks for your reply Mirek 
In my case the server no longer called do () after launching close (), I should have better read the documentation! 
The problem is rather client side, see below. 
 
I encountered several difficulties to write a client application (IoT) with Websocket class for the real world of the web, but it does not miss much: 
 
1) the connection header is currently fixed, it is essential to be able to modify it  
    => it could be something like a Vector <String> to adapt before connecting. 
 
2) Need a public function for really close the socket. Websoket :: Close does not close the socket but sends a request to the server. 
 If it does not respond for some reason, the client loops indefinitely (my first problem !) 
I replaced the Close by Disconnect (), and added a new Close (): 
void Disconnect (const String & msg = Null);       // old Close (), just a message to the server 
void Close () {socket-> Close ();}                 // real TCP close, even is server is sleeping... 
 
3) Sending Masked requests is not available. This works: 
    add this function in class WebSocket (Inet.h) :	 
        void   SendTextMasked(const String& data)           { SendRaw(MASK|FIN|TEXT, data); } 
 
    Change SendRaw() in WebSocket.cpp  : 
void WebSocket::SendRaw(int hdr, const String& data) 
{ 
	if(IsError())  
		return; 
	 
	ASSERT(!close_sent); 
	LLOG("Send " << data.GetCount() << " bytes, hdr: " << Format("%04X",hdr)); 
	 
	// mask detect 
	int LocMask = (hdr & MASK)?0x80:0; 
	hdr &= 0xFF; 
	 
	//---- header construct 
	// opcode 
	String header; 
	header.Cat(hdr); 
	 
	// Length 
	int len = data.GetCount(); 
	if(len > 65535) { 
		header.Cat(LocMask | 127); 
		header.Cat(0); 
		header.Cat(0); 
		header.Cat(0); 
		header.Cat(0); 
		header.Cat(byte(len >> 24)); 
		header.Cat(byte(len >> 16)); 
		header.Cat(byte(len >>  ); 
		header.Cat(byte(len)); 
	} 
	else 
	if(len > 125) { 
		header.Cat(LocMask | 126); 
		header.Cat(byte(len >>  ); 
		header.Cat(byte(len)); 
	} 
	else 
		header.Cat(LocMask |(int)len);	 
	 
	if (LocMask) 
	{ 
		//add masking-key 
		byte Cle[4]; 
		Cle[0] = Random(); 
		Cle[1] = Random(); 
		Cle[2] = Random(); 
		Cle[3] = Random();				 
		for(int i = 0; i < 4; i++)  header.Cat(Cle[i]); 
		 
		//---- send header with mask 
	    	Out(header); 
	     
	    //---- send masked data 
		if(data.GetCount() != 0) 
		{ 
			char buf[32768]; 
			int n = data.GetCount(); 
			for(int i = 0; i < n; i++)  
	        	buf[i] = data[i] ^ (byte) Cle[i & 3]; 
			Out(String(buf,n)); 
		} 
	} 
 
	else 
	{ 
        //---- send header (not masked) 
		Out(header); 
 
    	//--- send data (not masked) 
		if(data.GetCount() != 0) 
			Out(data); 
	} 
} 
hope this can help
		
		
		
 |  
	| 
		
	 | 
 
 
 |  
	| 
		
 |  
	| 
		
 |  
	| 
		
 |  
	
		
		
			| Re: How to close  the websocket connection [message #49555 is a reply to message #49554] | 
			Wed, 28 February 2018 23:27    | 
		 
		
			
				
				
				  | 
					
						  
						Klugier
						 Messages: 1106 Registered: September 2012  Location: Poland, Kraków 
						
					 | 
					Senior Contributor  | 
					 | 
		 
		 
	 | 
 
	
		Hello Mirek, 
 
Why not to keep request_headers as Vector: 
Vector<String> request_headers;
request_headers = { 
    "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"",
    "Accept-Language: cs,en-US;q=0.7,en;q=0.3",
    ...
};
// The user can add custom headers to the vector with more straight forward wait. Moreover user will not be obligated to remember about /r/n.
auto header = web_socket.StandardHeaders();
header.Add("Custom-header: data");
// Deletation is also trivial of any of the standard headers.
request_headers.Remove(1); // Remove ""Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"",", I don't need it!
// The set method also needs to be change
web_socket.RequestHeaders(request_headers);
 
 
 
\r\n can be added to the lines while processing. These approch is more flexible than String implementatino. Please let me know what do you think? 
 
Sincerely, 
Klugier 
		
		
  U++ - one framework to rule them all.
		[Updated on: Wed, 28 February 2018 23:40] Report message to a moderator  
 |  
	| 
		
	 | 
 
 
 |  
	
		
		
			| Re: How to close  the websocket connection [message #49560 is a reply to message #49555] | 
			Thu, 01 March 2018 16:55    | 
		 
		
			
				
				
				
					
						  
						uppjj
						 Messages: 9 Registered: February 2018  Location: France
						
					 | 
					Promising Member  | 
					 | 
		 
		 
	 | 
 
	
		hello all 
 
Mirek,  
-in SenRaw you also have to add "mask"  line 459 : 
   else header.Cat((int)len); => else header.Cat((int)len | mask);  
 
-your improvement ... no longer allows me to use "connect". Let me explain : 
 the server reject : "Get ws://serveur.example.com/chat/sensor-123 HTTP/1.1"   // the complete adress 
 but accept : "Get /chat/sensor-123 HTTP/1.1"     // sub adress 
 if followed by : "Host: server.example.com"    // site adress 
it is therefore essential to have acces to uri, which in some cases may be different from url.  
 
For the Vector, I am not sure a "Standard header" exist. User should have to delete unwanted items, which is a more complex job than to build all the Header. May be a vectormap with some predefined key "Get", "Host", "Upgrade",Sec-WebSocket-Key" etc.. would facilate the use with "/r/n" taking in account of course.  
 
A good idea should be to add the Websocket Protocol specification RF6455 example in the upp Websocket documentation, to help the user build his own header: 
The handshake from the client looks as follows: 
  GET /chat HTTP/1.1 
  Host: server.example.com 
  Upgrade: websocket 
  Connection: Upgrade 
  Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ== 
  Origin: http://example.com 
  Sec-WebSocket-Protocol: chat, superchat 
  Sec-WebSocket-Version: 13 
 
JJ
		
		
		
 |  
	| 
		
	 | 
 
 
 |  
	| 
		
 |  
	| 
		
 |  
	| 
		
 |  
	
		
		
			| Re: How to close  the websocket connection [message #49574 is a reply to message #48944] | 
			Sun, 04 March 2018 15:51   | 
		 
		
			
				
				
				
					
						  
						uppjj
						 Messages: 9 Registered: February 2018  Location: France
						
					 | 
					Promising Member  | 
					 | 
		 
		 
	 | 
 
	
		Ok thanks. This is working now with your new code, with url containing subfolder or not : 
 
// adress 
String Host,SubFolder; 
bool ssl; 
Adress_Split(Url,Host,SubFolder,ssl);   
// header 
WS_Client.ClearHeaders().Header("Upgrade","websocket").Header( "Connection","Upgrade").Header("Sec-WebSocket-Version", "13");  // may be standard part of header ? 
WS_Client.Header("Sec-WebSocket-Protocol","your_protocol")...;  // custom part  
// connect 
WS_Client.Connect(SubFolder,Host,ssl);   // ok working now ! 
... 
 
with : 
 
void Adress_Split(const String& url,String& host,String& Subfolder,bool& ssl) 
{// copy of the beginning of connect(url) 
	Subfolder = url; 
	const char *u = url; 
	ssl = memcmp(u, "wss", 3) == 0; 
	 
	//--- Host 
	const char *t = u; 
	while(*t && *t != '?') 
		if(*t++ == '/' && *t == '/')  
		{ 
			u = ++t; 
			break; 
		} 
	t = u; 
	while(*u && *u != ':' && *u != '/' && *u != '?') 
		u++; 
	host = String(t, u); 
	 
	//--- SubFolder (JJ) 
	while(*u && *u != '/' && *u != '?') u++; 
	if (*u !=0) Subfolder = u;  
} 
		
		
		
 |  
	| 
		
	 | 
 
 
 |   
Goto Forum:
 
 Current Time: Tue Nov 04 00:17:42 CET 2025 
 Total time taken to generate the page: 0.05108 seconds 
 |   
 |  
  |