Closed KillianKemps closed 4 years ago
@KillianKemps I’ve posted to our Gitter chat, to see if there are any Heroku users who may be able to help.
Perhaps @arome @nagyadam2092 who wrote the deployment guide might have some ideas?
hey @delucis ! Did the API change? I haven't had a look at boardgame.io in a while, and I don't remember this.client.start();
calls - maybe that's the issue?
Thanks @nagyadam2092! This is using the plain JavaScript client rather than the React one, so that’s where the start()
method comes from. The client code looks ok (and works locally), so I wonder if it’s something to do with the server config. That CORS error seems to happen quite often when a connection to the game server fails (not really related to CORS which is confusing.)
@KillianKemps How do you build the client on Heroku? Using something like parcel build index.html
?
@delucis Yes, here is the scripts
section of package.json
:
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "parcel index.html --open",
"serve": "node -r esm src/server.js",
"build": "parcel build index.html"
},
You can also directly test my deployment on https://boardgameio-tictactoe.herokuapp.com/
I also precise that I have set the environment variables on Heroku, in case it could be the source of the CORS error:
HOST=boardgameio-tictactoe.herokuapp.com
PORT=8000
If I try to connect to the server directly the request times out (e.g. via a socket URL or to access the lobby API), so I’d guess that’s the source of the CORS error (here are the error details on MDN).
According to the deployment docs, Heroku can use the start
script in the package.json
to run your application. Is it possible the start
script that runs parcel
is being preferred to the Procfile? Are there some logs you can check to confirm which script is running?
I finally made it work!
I first had the same doubt if Heroku used the right command, but it should use the Procfile
in priority when it is present.
I can confirm the right command is being used because I can see this in the logs when I access the app:
2020-10-07T09:53:16.724381+00:00 heroku[web.1]: Starting process with command `node -r esm src/server.js`
2020-10-07T09:53:21.023310+00:00 heroku[web.1]: State changed from starting to up
Concerning the CORS error, it looks like it may be a closed port issue. I have manually registered the PORT
environment variable to 8000
, but Heroku has to manage it itself.
I have now unregistered the HOST
and PORT
variables from Heroku. I also removed the .env.production
file I had for Parcel in which I first had put this:
HOST=boardgameio-tictactoe.herokuapp.com
PORT=$PORT
After have removed the environment variables, I changed this in App.js
:
- multiplayer: SocketIO({ server: `https://${process.env.HOST || 'localhost'}:${process.env.PORT || 8000}` }),
+ multiplayer: SocketIO({ server: `https://${window.location.hostname}` }),
Now, the socket.io requests work by directly accessing https://boardgameio-tictactoe.herokuapp.com/
without having to specify the port number.
Coming back to the Heroku deployment guide, as it was specified for the Lobby to use https://${window.location.hostname}
, I think it would be nice to add that we need to configure the same thing in App.js
for the client constructor.
I copy here again my files in order to help others:
server.js
:
import { Server } from 'boardgame.io/server';
import path from 'path';
import serve from 'koa-static';
import { TicTacToe } from './Game';
const server = Server({ games: [TicTacToe] });
const PORT = process.env.PORT || 8000;
// Build path relative to the server.js file
const frontEndAppBuildPath = path.resolve(__dirname, '../dist');
server.app.use(serve(frontEndAppBuildPath))
server.run(PORT, () => {
server.app.use(
async (ctx, next) => await serve(frontEndAppBuildPath)(
Object.assign(ctx, { path: 'index.html' }),
next
)
)
});
Beginning of App.js
:
import { SocketIO } from 'boardgame.io/multiplayer';
import { TicTacToe } from './Game';
class TicTacToeClient {
constructor(rootElement, { playerID } = {}) {
this.client = Client({
game: TicTacToe,
multiplayer: SocketIO({ server: `https://${window.location.hostname}` }),
playerID
});
this.client.start();
this.rootElement = rootElement;
this.createBoard();
this.attachListeners();
this.client.subscribe(state => this.update(state));
}
Thanks for helping!
Note: in fact my solution is not suitable for local developing anymore. As the port is not specified, Socket.io can't connect to the local server like localhost:8000
.
So, here is the right App.js
to make the connection work locally and on the server without using environment variables:
import { Client } from 'boardgame.io/client';
import { SocketIO } from 'boardgame.io/multiplayer';
import { TicTacToe } from './Game';
class TicTacToeClient {
constructor(rootElement, { playerID } = {}) {
this.client = Client({
game: TicTacToe,
multiplayer: SocketIO({ server: `${window.location.protocol}//${window.location.hostname}:${window.location.port}` }),
playerID
});
this.client.start();
this.rootElement = rootElement;
this.createBoard();
this.attachListeners();
this.client.subscribe(state => this.update(state));
}
Hello,
I read previous issues #571 #319 and also the Heroku deployment guide, but I still have issues to make the TicTacToe work on Heroku.
I'm able to run
npm run serve
and to play TicTacToe locally on http://localhost:8000However, on Heroku when I click on a cell I get this error in the console:
Uncaught TypeError: can't access property "currentPlayer", r.ctx is undefined
.Also, several minutes later I get these errors in the console:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://boardgameio-tictactoe.herokuapp.com:8000/socket.io/?EIO=3&transport=polling&t=NJ-DnWk. (Reason: CORS request did not succeed).
Here is the
Procfile
for Heroku:Here is the entire
server.js
file:And here the beginning of
App.js
:Can you tell what may be missing?