Problem with second connect to the room

Options
liget
liget
edited April 2013 in Tutorials and Code Sharing
hi all,

I have a problem with second connect to the room.

1) The first client create Room.
2) After that, client 1 loading level and spawn character.
3) Joining to this room from second client.
4) Second client loading same level and create character.
5) Close second client
6) Run second client again
7) Joining to the room

After that, on the second client, level loaded, but character not created.
Display many errors in Log:
1) Received unknown status code: QueueIncomingReliableWarning
2) Cannot send messages when not connected; Either connect to Photon OR use offline mode!

All RPC functions on second client display errors in log.
I have no idea how to fix that.

Can anybody help?

[code2=csharp]using UnityEngine;
using System.Collections;
using ExitGames.Client.Photon;

public class NetworkController : Photon.MonoBehaviour {

public string gameName;
public int maxPlayers = 5;

string level = "spaceBox";

bool drawRoomCreation;
bool drawRoomsList;

private float btnX = Screen.width * 0.05f;
private float btnY = Screen.width * 0.05f;
private float btnW = Screen.width * 0.2f;
private float btnH = Screen.width * 0.2f;


void OnGUI()
{

GUI.Label (new Rect(Screen.width / 2f, Screen.height / 2f, 150f, 60f), "Connection: " + PhotonNetwork.connected);
GUI.Label (new Rect(Screen.width / 2f, (Screen.height / 2f) + 20, 100f, 60f), "Players in Lobby: " + PhotonNetwork.countOfPlayersOnMaster);

if(!PhotonNetwork.connected){
DrawConnectButton();
}
else
{
DrawDisconnectButton();
DrawRoomsButtons();
}

if(drawRoomsList)
{
DrawRoomsList();
}

if(drawRoomCreation)
{
Debug.Log ("Draw text field");
GUI.Box (new Rect(Screen.width / 2, Screen.height / 2, 150, 30), "");
gameName = GUI.TextField(new Rect(Screen.width / 2, Screen.height / 2, 150, 30), gameName, 25);

if(GUI.Button (new Rect(Screen.width / 2, (Screen.height / 2) + 40, 150, 30), "OK"))
{
string[] roomProperties = {"map", level};
Hashtable customRoomProperties = new Hashtable() {{"map", level}};
PhotonNetwork.CreateRoom(gameName, true, true, 20, customRoomProperties, roomProperties);
}
}

}

void DrawConnectButton ()
{
if(GUI.Button(new Rect(Screen.width / 2, (Screen.height / 2) - 60, 150, 60), "Connect to server"))
{
PhotonNetwork.ConnectUsingSettings("v1.0");
}
}

void DrawDisconnectButton ()
{
if(GUI.Button(new Rect(Screen.width - 150, (Screen.height / 2) - 60, 150, 60), "Disconnect"))
{
PhotonNetwork.Disconnect();
}
}

void DrawRoomsButtons ()
{
if(GUI.Button(new Rect(btnX, btnY, btnW, btnH), "Create Room"))
{
drawRoomCreation = true;
}
if(GUI.Button(new Rect(btnX, btnY * 1.2f + btnH, btnW, btnH), "Show availble Rooms"))
{
drawRoomsList = true;
}
}

void DrawRoomsList()
{
int _a = 0;

foreach(RoomInfo game in PhotonNetwork.GetRoomList())
{
if(GUI.Button(new Rect(30, 15 * _a + 3, 150, 40), game.name))
{
PhotonNetwork.JoinRoom(game);
_a++;
}
}
}

void OnCreatedRoom()
{
Debug.Log ("Room created");
PhotonNetwork.LoadLevel(level);
}

void OnJoinedRoom()
{
if(PhotonNetwork.connected)
{
PhotonNetwork.RemoveRPCs();
PhotonNetwork.LoadLevel(level);
}
}

void OnDisconnectedFromPhoton()
{

}

void OnFailedToConnectToPhoton(object parameters)
{

}

public void OnMasterClientSwitched(PhotonPlayer player)
{

}

public void OnReceivedRoomList()
{

}

public void OnReceivedRoomListUpdate()
{

}

public void OnConnectedToPhoton()
{
Debug.Log("OnConnectedToPhoton");
}

public void OnFailedToConnectToPhoton()
{
Debug.Log("OnFailedToConnectToPhoton");
}

public void OnPhotonInstantiate(PhotonMessageInfo info)
{
Debug.Log("OnPhotonInstantiate " + info.sender);
}

// Use this for initialization
void Start () {
PhotonNetwork.isMessageQueueRunning = false;
}

// Update is called once per frame
void Update () {
Debug.Log ("Network manager is alive");
}
}[/code2]

Comments

  • Tobias
    Options
    Why are you deleting RPCs when you join a room?
    We implemented a synchronization for the loaded level into PUN 1.18. If you got that from the AssetStore, you could use:
    PhotonNetwork.automaticallySyncScene
    and
    PhotonNetwork.LoadLevel(string levelTitle)
  • liget
    Options
    Thank you! But it does not work. I still have a same problem.

    I had modified my script:
    [code2=csharp]void OnJoinedRoom()
    {
    if(PhotonNetwork.connected)
    {
    PhotonNetwork.automaticallySyncScene = true;
    if(PhotonNetwork.isMasterClient){
    PhotonNetwork.LoadLevel(level);
    }
    }
    }[/code2]
  • Tobias
    Options
    Are you still deleting the RPCs?
    Any log output?
  • Tobias
    Options
    Are you still deleting the RPCs?
    Any log output?
  • liget
    Options
    No. I have remove PhotonNetwork.RemoveRPCs();

    And yes on second connect client is log out:
    1) Received unknown status code: QueueIncomingReliableWarning
    2) Cannot send messages when not connected; Either connect to Photon OR use offline mode

    I don't know why
  • liget
    Options
    Here the final script:
    [code2=csharp]using UnityEngine;
    using System.Collections;
    using ExitGames.Client.Photon;

    public class NetworkController : Photon.MonoBehaviour {

    public string gameName; //Название комнаты. Если не определяется в редакторе, то при старте присваиваем сами.
    public int maxPlayers = 5; // Максимальное количество игроков в комнате

    string level = "spaceBox"; // Уровень который загружается при старте

    bool drawRoomCreation;
    bool drawRoomsList;

    //Определяем размер и положение кнопок
    private float btnX = Screen.width * 0.05f;
    private float btnY = Screen.width * 0.05f;
    private float btnW = Screen.width * 0.2f;
    private float btnH = Screen.width * 0.2f;


    void OnGUI()
    {
    //Отображаем статус подключения
    GUI.Label (new Rect(Screen.width / 2f, Screen.height / 2f, 150f, 60f), "Connection: " + PhotonNetwork.connected);
    //Отображаем количество игроков в лобби
    GUI.Label (new Rect(Screen.width / 2f, (Screen.height / 2f) + 20, 100f, 60f), "Players in Lobby: " + PhotonNetwork.countOfPlayersOnMaster);

    if(!PhotonNetwork.connected){
    //Рисуем кнопку Connect
    DrawConnectButton();
    }
    else
    {
    DrawDisconnectButton();
    DrawRoomsButtons();
    }

    if(drawRoomsList)
    {
    DrawRoomsList();
    }

    if(drawRoomCreation)
    {
    Debug.Log ("Draw text field");
    GUI.Box (new Rect(Screen.width / 2, Screen.height / 2, 150, 30), "");
    gameName = GUI.TextField(new Rect(Screen.width / 2, Screen.height / 2, 150, 30), gameName, 25);

    if(GUI.Button (new Rect(Screen.width / 2, (Screen.height / 2) + 40, 150, 30), "OK"))
    {
    string[] roomProperties = {"map", level};
    Hashtable customRoomProperties = new Hashtable() {{"map", level}};
    PhotonNetwork.CreateRoom(gameName, true, true, 20, customRoomProperties, roomProperties);
    }
    }

    }

    void DrawConnectButton ()
    {
    if(GUI.Button(new Rect(Screen.width / 2, (Screen.height / 2) - 60, 150, 60), "Connect to server"))
    {
    PhotonNetwork.ConnectUsingSettings("v1.0");
    }
    }

    void DrawDisconnectButton ()
    {
    if(GUI.Button(new Rect(Screen.width - 150, (Screen.height / 2) - 60, 150, 60), "Disconnect"))
    {
    PhotonNetwork.Disconnect();
    }
    }

    void DrawRoomsButtons ()
    {
    if(GUI.Button(new Rect(btnX, btnY, btnW, btnH), "Create Room"))
    {
    drawRoomCreation = true;
    }
    if(GUI.Button(new Rect(btnX, btnY * 1.2f + btnH, btnW, btnH), "Show availble Rooms"))
    {
    drawRoomsList = true;
    }
    }

    void DrawRoomsList()
    {
    int _a = 0;

    foreach(RoomInfo game in PhotonNetwork.GetRoomList())
    {
    if(GUI.Button(new Rect(30, 15 * _a + 3, 150, 40), game.name))
    {
    PhotonNetwork.JoinRoom(game);
    _a++;
    }
    }
    }

    void OnCreatedRoom()
    {
    Debug.Log ("Room created");
    }

    void OnJoinedRoom()
    {
    if(PhotonNetwork.connected)
    {
    PhotonNetwork.automaticallySyncScene = true;
    if(PhotonNetwork.isMasterClient){
    PhotonNetwork.LoadLevel(level);
    }
    }
    }

    void OnDisconnectedFromPhoton()
    {

    }

    void OnFailedToConnectToPhoton(object parameters)
    {

    }

    public void OnMasterClientSwitched(PhotonPlayer player)
    {

    }

    public void OnReceivedRoomList()
    {

    }

    public void OnReceivedRoomListUpdate()
    {

    }

    public void OnConnectedToPhoton()
    {
    Debug.Log("OnConnectedToPhoton");
    }

    public void OnFailedToConnectToPhoton()
    {
    Debug.Log("OnFailedToConnectToPhoton");
    }

    public void OnPhotonInstantiate(PhotonMessageInfo info)
    {
    Debug.Log("OnPhotonInstantiate " + info.sender);
    }

    // Use this for initialization
    void Start () {
    //PhotonNetwork.isMessageQueueRunning = true;
    }

    // Update is called once per frame
    void Update () {
    Debug.Log ("Network manager is alive");

    }
    }[/code2]
  • Tobias
    Options
    Final as in "working"?
  • liget
    Options
    No. :(
  • liget
    Options
    Hi again. :)

    I still have a problem.

    Second client has disconnect, if he was connect and level was loaded after the first client make changes in level (On\off light, open the door, every activity with RPC functions with PhotonTargets.AllBuffered).

    After disconnect did not calling OnDisconnectedFromPhoton().

    Errors:
    1) Received unknown status code: QueueIncomingReliableWarning (after level loaded)
    2) Cannot send messages when not connected; Either connect to Photon OR use offline mode! (after player spawned)
  • Tobias
    Options
    While you load the level, it seems your client gets a lot of messages (buffered ones, e.g.). This is why you get 1. You should improve what you buffer.
    The 2nd error you get means you got disconnected but your game logic tries to send data despite the current connection state (disconnected). Make your client not send while disconnected.

    Sending light on/off as RPC is inefficient. Much more so, when you buffer it.
    Imagine: Each RPC is a note in your mailbox. Unbuffered ones get read when they arrive while you watch your mail but buffered ones stay in the box. Every time you check your box you have to read all buffered messages.
    At some point, you give up.

    You could use Room properties for the state of the light. This is one note which gets updated all the time.
  • liget
    Options
    mmm... I have a really many objects to synchronize.
    Do i have a option to take last state of objects with attached PhotonView when i connect to the room?
  • Tobias
    Options
    Like I said: RPCs are not updating a state (a single note) but are individual notes each.
    You will have to arrange the updates in another way to cause less traffic.

    What are you trying to do with how many objects and which frequency?
  • liget
    Options
    My game is about control the space ship on isometric view. In the ship have a many devices to control - oxygen controllers in every room, gravity controllers, energy controllers, door controllers e.t.c Something about 10 - 15 devices for now, and 50 - 70 in final version.
    RPC functions was calling in every device when level is loaded (adding device to power source) and if somebody make something with this device.
  • liget
    Options
    And one more thing. It's working on Unity Network.
    You can check it here (the early prototype): :)
    http://spawnmore.com/web.html

    If you use anyone device and will change device state (push on\off button), and connect with second client - it's work fine. But does not work on Photon.
  • Tobias
    Options
    This really sounds like you could use properties rather than RPCs for state info.
    Room properties are a hashtable with string keys. You should keep those as short as possible.
    To set only one key's value, you don't have to send more than that to the server. All key-values will be sent to new players in one go, updating them with the latest state and from there on providing updates.
    You should experiment with that.
  • liget
    Options
    Ok. I'll try.
    Thanks Tobias
  • liget
    Options
    Ok. I've made an experiment and replaced all PhotonTargets.AllBuffered, on PhotonTargets.All.
    For now all RPC actions not buffered.

    Second player not disconnected now. But error "Received unknown status code: QueueIncomingReliableWarning" still here.
  • Tobias
    Options
    Buffering RPCs (or not) only matter for players who join into a running game. The buffer gets them whatever you wanted buffered. If you don't buffer, joining players don't get what happened before in the room.
    If you still get the error, you are still sending a lot of RPCs at the same time, so your clients' queues fill up a lot before the messages get executed (and queues shrink accordingly).

    I meant using SetProperties instead of using a lot of RPCs. Where you only want the "current" state, you can use a property to store that state. It can be updated.