x

Search in
Sort by:

Question Status:

Search help

  • Simple searches use one or more words. Separate the words with spaces (cat dog) to search cat,dog or both. Separate the words with plus signs (cat +dog) to search for items that may contain cat but must contain dog.
  • You can further refine your search on the search results page, where you can search by keywords, author, topic. These can be combined with each other. Examples
    • cat dog --matches anything with cat,dog or both
    • cat +dog --searches for cat +dog where dog is a mandatory term
    • cat -dog -- searches for cat excluding any result containing dog
    • [cats] —will restrict your search to results with topic named "cats"
    • [cats] [dogs] —will restrict your search to results with both topics, "cats", and "dogs"

Office Holiday

Epic Games' offices will be on holiday from June 22nd to July 7th. During this period support will be limited. Our offices will reopen on Monday, July 8th. 

Compiler error extending FRunnableThread

Compiler crashes when trying to extend class FRunnableThread

 2>EXEC : error : Couldn't find parent type for 'ServerThread' named 'FRunnableThread' in current module or any other module parsed so far.
 2>Error : Failed to generate code for RenderServerEditor - error code: OtherCompilationError (5)
 2>  UnrealHeaderTool failed for target 'RenderServerEditor' (platform: Win64, module info: D:\Unreal_Projects\RenderServer\Intermediate\Build\Win64\RenderServerEditor\Development\UnrealHeaderTool.manifest).
 2>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V120\Microsoft.MakeFile.Targets(38,5): error MSB3073: The command ""D:\UnrealEngine4\Epic Games\4.9\Engine\Build\BatchFiles\Build.bat" RenderServerEditor Win64 Development "D:\Unreal_Projects\RenderServer\RenderServer.uproject" -rocket -waitmutex" exited with code -1.


This is the code that crashes

 // Fill out your copyright notice in the Description page of Project Settings.
 
 #pragma once
 
 #include "CoreGlobals.h"
 #include "SocketServer.h"
 #include "Object.h"
 #include "ServerThread.generated.h"
 
 
 /**
  * 
  */
 UCLASS()
 class RENDERSERVER_API UServerThread : public FRunnableThread;
 {
     GENERATED_BODY()
     
     
     
     
 };

Thanks in advance for the help :D

Product Version: UE 4.9
Tags:
more ▼

asked Oct 22 '15 at 08:25 AM in C++ Programming

avatar image

Elmeta
1 1 2 3

(comments are locked)
10|2000 characters needed characters left
Viewable by all users

1 answer: sort voted first

I think what you want to do is to create a run-able that holds it's own thread. If yes you should not inherit from FRunableThread, you have to use it. The next snippet is a sample implementation of a server that listens to connections on a separate thread.

 // RunableServer.h
 //
 // Copyright (c) 2015 Moritz Wundke
 // MIT License
 //
 
 #pragma once
 
 #include "Networking.h"
 #include "TcpListener.h"
 
 // Default endpoint for the server
 #define DEFAULT_ENDPOINT FIPv4Endpoint(FIPv4Address(127, 0, 0, 1), 5005)
 
 /**
  * Server listening on a TCP socket
  */
 class FRunableServer
     : public FRunnable
 {
 public:
     FUnrealEdRemoteServer();
 
     ~FUnrealEdRemoteServer();
 
     /** FRunnable init */
     virtual bool Init() override;
 
     /** FRunnable loop */
     virtual uint32 Run() override;
 
     bool HandleListenerConnectionAccepted(class FSocket* ClientSocket, const FIPv4Endpoint& ClientEndpoint);
 
     /**
     * Checks whether the listener is listening for incoming connections.
     *
     * @return true if it is listening, false otherwise.
     */
     bool IsActive() const
     {
         return (!Stopping);
     }
 
     virtual void Stop() override
     {
         Stopping = true;
     }
 
     virtual void Exit() override { }
 
 private:
     class FTcpListener *Listener = NULL;
 
     /** Current clients and pending to get accepted clients */
     TQueue<class FSocket*, EQueueMode::Mpsc> PendingClients;
     TArray<class FSocket*> Clients;
 
     /** Used to tell that the thread is stopping */
     bool Stopping;
 
     /** Connection thread, used to not block the editor when waiting for connections */
     FRunnableThread* Thread = NULL;
 
     /** Basic message handling, your implementation will be in here */
     FString HandleClientMessage(const FSocket *Socket, const FString& Message);
 };

And the CPP

 // RunableServer.cpp
 //
 // Copyright (c) 2015 Moritz Wundke
 // MIT License
 //
 
 #include "RunableServer.h"
 #include "Runtime/Core/Public/Misc/CString.h"
 
 FRunableServer::FRunableServer()
     : Listener(NULL), Thread(NULL)
 {
     Thread = FRunnableThread::Create(this, TEXT("FRunableServer"), 8 * 1024, TPri_Normal);
 }
 
 FRunableServer::~FRunableServer()
 {
     // Stop the runnable
     Stop();
 
     // Stop accepting clients first
     if (Listener != NULL)
     {
         Listener->Stop();
         delete Listener;
         Listener = NULL;
     }
 
     // Kill all pending connections and current connections
     if (!PendingClients.IsEmpty())
     {
         FSocket *Client = NULL;
         while (PendingClients.Dequeue(Client))
         {
             Client->Close();
         }
     }
     for (TArray<class FSocket*>::TIterator ClientIt(Clients); ClientIt; ++ClientIt)
     {
         (*ClientIt)->Close();
     }
 
     // And last but not least stop the main thread
     if (Thread != NULL)
     {
         Thread->Kill(true);
         delete Thread;
     }
 }
 
 bool FRunableServer::HandleListenerConnectionAccepted(class FSocket* ClientSocket, const FIPv4Endpoint& ClientEndpoint)
 {
     PendingClients.Enqueue(ClientSocket);
     return true;
 }
 
 bool FRunableServer::Init()
 {
     if (Listener == NULL)
     {
         Listener = new FTcpListener(DEFAULT_ENDPOINT);
         Listener->OnConnectionAccepted().BindRaw(this, &FUnrealEdRemoteServer::HandleListenerConnectionAccepted);
         Stopping = false;
     }
     return (Listener != NULL);
 }
 
 /** Send a string message over to a socket */
 bool SendMessage(FSocket *Socket, const FString& Message)
 {
     check(Socket);
     int32 BytesSent = 0;
     return Socket->Send((uint8*)TCHAR_TO_UTF8(*Message), Message.Len(), BytesSent);
 }
 
 /** Receive a string message from a socket */
 bool RecvMessage(FSocket *Socket, uint32 DataSize, FString& Message)
 {
     check(Socket);
 
     FArrayReaderPtr Datagram = MakeShareable(new FArrayReader(true));
     Datagram->Init(FMath::Min(DataSize, 65507u));
 
     int32 BytesRead = 0;
     if (Socket->Recv(Datagram->GetData(), Datagram->Num(), BytesRead))
     {
         char* Data = (char*)Datagram->GetData();
         Data[BytesRead] = '\0';
         Message = UTF8_TO_TCHAR(Data);
         return true;
     }
     return false;
 }
 
 uint32 FRunableServer::Run()
 {
     while (!Stopping)
     {
         if (!PendingClients.IsEmpty())
         {
             FSocket *Client = NULL;
             while (PendingClients.Dequeue(Client))
             {
                 Clients.Add(Client);
             }
         }
 
         // remove closed connections
         for (int32 ClientIndex = Clients.Num() - 1; ClientIndex >= 0; --ClientIndex)
         {
             if (Clients[ClientIndex]->GetConnectionState() != SCS_Connected)
             {
                 Clients.RemoveAtSwap(ClientIndex);
             }
         }
 
         // Poll data from every connected client
         for (TArray<class FSocket*>::TIterator ClientIt(Clients); ClientIt; ++ClientIt)
         {
             FSocket *Client = *ClientIt;
             uint32 DataSize = 0;
             while (Client->HasPendingData(DataSize))
             {
                 FString Request;
                 if (RecvMessage(Client, DataSize, Request))
                 {
                     FString Response = HandleClientMessage(Client, Request);
                     SendMessage(Client, Response);
                 }
             }
         }
 
         FPlatformProcess::Sleep(0.2f);
     }
 
     return 0;
 }
 
 FString FRunableServer::HandleClientMessage(const FSocket *Socket, const FString& Message)
 {
     bool bProcessed = false;
     FString Response;
 
     // TODO: Here goes your code to handle the actual message
     
     return bProcessed ? TEXT("OK") : TEXT("KO");
 }
 

NOTE: The code might need some tweaks but you should see how I'm using the thread in here

more ▼

answered Oct 22 '15 at 02:05 PM

avatar image

Moss
6.4k 127 98 606

avatar image Elmeta Oct 27 '15 at 09:18 AM

Thank you very much for your help. It really helped me

avatar image Moss Oct 27 '15 at 09:22 AM

Remember to accept the answer

avatar image erik321123 Jul 12 '17 at 08:10 PM

I know this post has been closed over a year ago, but I just had a few questions and hoped you (@Moss) can answer them. How do you create this thread, and does this work for the multithreading part (also with closing the thread)?

(comments are locked)
10|2000 characters needed characters left
Viewable by all users
Your answer
toggle preview:

Up to 5 attachments (including images) can be used with a maximum of 5.2 MB each and 5.2 MB total.

Follow this question

Once you sign in you will be able to subscribe for any updates here

Answers to this question