Jump to content

Recommended Posts

Posted

Hey,

So I am experimenting with websockets and I've got a server running but now I want to be able to save some of the I/O to pages. I thought i just bootstrap (http://processwire.com/api/include/) to my server and it'll work.

No

This is the message i get running CMD.exe:

 Error: Call to a member function get() on a non-object (line 40 of C:\wamp\www\social\server.php) 
This error message was shown becuase you are using the command line API. Error has been logged.

And the server crashes and disconnects all clients.

This is the entire code of the server.php: (Located in the PW Root folder).

<?php
include("C:\wamp\www\social\index.php"); 
// prevent the server from timing out
set_time_limit(0);

// include the web sockets server script (the server is started at the far bottom of this file)
require 'class.PHPWebSocket.php';

// when a client sends data to the server
function wsOnMessage($clientID, $message, $messageLength, $binary) {
	global $Server;
	$ip = long2ip( $Server->wsClients[$clientID][6] );

	// check if message length is 0
	if ($messageLength == 0) {
		$Server->wsClose($clientID);
		return;
	}

	//The speaker is the only person in the room. Don't let them feel lonely.
	if ( sizeof($Server->wsClients) == 1 ){
		$Server->wsSend($clientID, "There isn't anyone else in the room, but I'll still listen to you. --Your Trusty Server");
		print($item->text);
	}
	else
		//Send the message to everyone but the person who said it
		foreach ( $Server->wsClients as $id => $client )
			if ( $id != $clientID ){
				$Server->wsSend($id, "Visitor $clientID ($ip) said \"$message\"");
			}
}

// when a client connects
function wsOnOpen($clientID)
{
	global $Server;
	$ip = long2ip( $Server->wsClients[$clientID][6] );

	$Server->log( "$ip ($clientID) has connected." );
	$item = $wire->pages->get('template=item');
	$Server->log($item->text);

	//Send a join notice to everyone but the person who joined
	foreach ( $Server->wsClients as $id => $client )
		if ( $id != $clientID )
			$Server->wsSend($id, "Visitor $clientID ($ip) has joined the room.");
}

// when a client closes or lost connection
function wsOnClose($clientID, $status) {
	global $Server;
	$ip = long2ip( $Server->wsClients[$clientID][6] );

	$Server->log( "$ip ($clientID) has disconnected." );

	//Send a user left notice to everyone in the room
	foreach ( $Server->wsClients as $id => $client )
		$Server->wsSend($id, "Visitor $clientID ($ip) has left the room.");
}

// start the server
$Server = new PHPWebSocket();
$Server->bind('message', 'wsOnMessage');
$Server->bind('open', 'wsOnOpen');
$Server->bind('close', 'wsOnClose');
// for other computers to connect, you will probably need to change this to your LAN IP or external IP,
// alternatively use: gethostbyaddr(gethostbyname($_SERVER['SERVER_NAME']))
$Server->wsStartServer('127.0.0.1', 9300);

?> 
 
Posted

Always in functions:

wire('pages')->get()
// Not $wire->pages or $pages

Seems like this problem comes up twice per day :)

Does it work?

  • Like 1
Posted

Always in functions:

wire('pages')->get()
// Not $wire->pages or $pages

Seems like this problem comes up twice per day :)

Does it work?

The bootstrap docs (http://processwire.com/api/include/) say that...

These two are equivalent, so what syntax you prefer to use is up to you:
 
$mypage = $wire->pages->get("/about/contact/"); 
$mypage = wire('pages')->get("/about/contact/"); 

:wacko:  :undecided: .....maybe it needs to be more explicit in the docs about functions... :)

Posted

Yep, they are equivalent.

Problem is PHP related: In a function, the variables outside are not recognized - out of scope.

So in this case here, it's the $wire variable which is unkown IN the function. Outside the function, it should work I guess.

There are quite a lot of topics dealing with this problem, but usually its the $pages or $page variable

which does not work, but same story here with $wire.

For further information: http://php.net/manual/en/language.variables.scope.php

Posted

 Problem is PHP related: In a function, the variables outside are not recognized - out of scope.

So in this case here, it's the $wire variable which is unkown IN the function. Outside the function, it should work I guess.

so, the OP also uses other variables in his functions from global scope:

global $Server;

he also can set it like this:

global $Server, $wire;

and than it should work.

But personally I only use the wire('something')->Version within functions. :)

  • Like 1
Posted

Thx for the links Wanze. In my case, initially, I thought it was only in Modules that I'd use wire. I was working on a function last week and gotcha! out of scope bit me :).

I think as the forum grows, we'll need a FAQ board to point out such issues. 

  • Like 1
Posted

Always in functions:

wire('pages')->get()
// Not $wire->pages or $pages

Seems like this problem comes up twice per day :)

Does it work?

Yeah it does work.

I think i was thinking too quick and the docs confused me

thanks a lot!

Posted

This particular subject has come up so often in the forum, because there's so many non-coders attracted by ProcessWire.

Every coder knows about scopes and variables and it's the same in all programming languages. I'm sure even if there's a FAQ or documentation on this subject people will run into this when they get their hands dirty. It's much like jQuery doesn't have any documentation for the Javascript language as it's not in its scope.

Posted

True but maybe something we can point everyone to to have a read...sort of "before posting, please read the FAQs first...your question may already have been answered" kinda thing. This is difficult to enforce though...:)

Posted

As I recognize it, those people running into this, don't even know about it, how they gonna look on something they don't know about?

Posted

Hmmm.. I am talking about a FAQ that is divided into different sections covering various things that come up often such as where is the admin page? Why can't I sort my pages in the tree?  Can PW handle thousands of pages? etc, etc..Of course we cannot cover all scenarios. 

Posted

I'm talking about the function scope issue and other tricky stuff that requires general coding knowledge.

Posted

Yes :D

Just to clarify, do you mean a FAQ on the website because in the forums there's already a FAQ board?

  • Like 1
Posted

It might not be a bad idea to mention it on the module page on the site at the start so folks writing their first module will read it though.

I think modules in ProcessWire will attract those with relatively less coding knowledge because it looks fairly easy, so even just a short paragraph starting with "a note about scope..." might be an idea with a link for more info.

Assuming people are starting their modules by reading that page first of course ;) Could also have a comment in the Hello World module about it, but I agree that sooner or later you will have to draw the line or you could have more comments than code very quickly :)

Posted

Yes :D

Just to clarify, do you mean a FAQ on the website because in the forums there's already a FAQ board?

What?!! I totally missed that. When did that get there?!! I told you it will be difficult to enforce...hehe. 

Maybe on both?

  • 1 year later...
Posted

Hello Harmster,

nice to see a websocket example here.

require 'class.PHPWebSocket.php'; 

Is it a self written class? Or which one did you use?

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...