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"

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 99 607

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