Websocket Failing To Connect but only in packaged build

I am using the Websockets module to establish a connection to a server. I have authored a latent blueprint node that, given a websocket (with a URL, protocol headers, etc.), can connect to the server, and includes a pass by reference boolean indicating success:

void UHttpBlueprintFunctionLibrary::ConnectToSocket(UObject* WorldContextObject, struct FLatentActionInfo LatentInfo, FSocketStruct SStruct, bool& bSuccess)
{
	class FXWebSocketConnectLatentAction : public FPendingLatentAction
	{
	public:
		// handle delegates
		FDelegateHandle ConnectedHandler;
		FDelegateHandle ConnectionErrorHandler;
		FDelegateHandle OnMessageHandler;

		FXWebSocketConnectLatentAction(const FLatentActionInfo& LatentInfo, TSharedPtr<IWebSocket> Socket, bool &ConnResult)
			: ExecutionFunction(LatentInfo.ExecutionFunction)
			, OutputLink(LatentInfo.Linkage)
			, CallbackTarget(LatentInfo.CallbackTarget)
			, WebSocket(Socket)
			, ConnectionResult(ConnResult)
			, Timer(0.0f)
		{
			ConnectedHandler = Socket->OnConnected().AddLambda([&ConnResult]() -> void {
				GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Cyan, "Connected to Hansoft Server");
				UE_LOG(LogHansoftBug, Display, TEXT("Connected to Hansoft Server"));
				ConnResult = true;
				});

			ConnectionErrorHandler = Socket->OnConnectionError().AddLambda([&ConnResult](const FString& ErrorMsg) -> void {
				UE_LOG(LogHansoftBug, Display, TEXT("Got connection result %s"), *ErrorMsg);
				ConnResult = false;
				});

			OnMessageHandler = Socket->OnMessage().AddLambda([](const FString& Message) -> void {
				// This code will run when we receive a string message from the server.
				UE_LOG(LogHansoftBug, Display, TEXT("Received message from Hansoft: %s"), *Message);
				GEngine->AddOnScreenDebugMessage(-1, 10.0f, FColor::Yellow, "Received message: " + Message);
				});

			// connect after establishing lambdas
			Socket->Connect();
		}

		~FXWebSocketConnectLatentAction()
		{
			WebSocket->OnConnected().Remove(ConnectedHandler);
			WebSocket->OnConnectionError().Remove(ConnectionErrorHandler);
			WebSocket->OnMessage().Remove(ConnectionErrorHandler);
		}

		// Variables for latent action info
		FName ExecutionFunction;
		int32 OutputLink;
		FWeakObjectPtr CallbackTarget;
		TSharedPtr<IWebSocket> WebSocket;
		bool& ConnectionResult;
		float Timer;

		// check for completion function
		virtual void UpdateOperation(FLatentResponse& Response) override
		{
			Timer += Response.ElapsedTime();
			if (ConnectionResult)
			{
				Response.FinishAndTriggerIf(true, ExecutionFunction, OutputLink, CallbackTarget);
			}
			if (Timer >= 10.0f) // 10s timeout
			{
				ConnectionResult = false;
				Response.FinishAndTriggerIf(true, ExecutionFunction, OutputLink, CallbackTarget);
			}
		}
	};

	// Add the latent action to the manager
	FXWebSocketConnectLatentAction* CompletionAction = nullptr;
	FLatentActionManager& LatentActionManager = WorldContextObject->GetWorld()->GetLatentActionManager();
	if (LatentActionManager.FindExistingAction<FXWebSocketConnectLatentAction>(LatentInfo.CallbackTarget, LatentInfo.UUID) == nullptr)
	{
		CompletionAction = new FXWebSocketConnectLatentAction(LatentInfo, SStruct.Socket, bSuccess);

		LatentActionManager.AddNewAction(LatentInfo.CallbackTarget, LatentInfo.UUID, CompletionAction);
	}
}

Where SSocketStruct is a simple UStruct containing only one TSharedPtr<IWebSocket> member.

When playing my game in editor, the function above works flawlessly, opening a connection, allowing me to see the relevant OnConnected() logging, and getting the successful result in the output.

However, when I package the game and run the same function, the connection to the websocket times out and I see the message “client_connect_failed” in the OnConnectionError() callback.

I followed the steps on this very similar post ensuring that my target platform is correct (Win64 in this case), copying the cacert.pem file into my project’s content directory and re-cooking, but still, no avail.

Any help would be greatly appreciated!

1 Like

Ok so I did end up figuring this out - it turns out in using an ip address instead of a URL to connect to my server, my packaged build wasn’t able to connect. Putting this IP behind a real URL seemed to solve the problem