Wednesday, 3 October 2018

react socket.io


package.json

{
  "name": "react-socketio",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "concurrently": "^4.0.1",
    "react": "^16.5.2",
    "react-dom": "^16.5.2",
    "react-scripts": "1.1.5",
    "socket.io-client": "^2.1.1"
  },
  "scripts": {
    "start": "concurrently --kill-others \"node server/server.js\" \"react-scripts start\"",
    "build": "react-scripts build",
    "test": "react-scripts test --env=jsdom",
    "eject": "react-scripts eject"
  },
  "devDependencies": {}
}

------------------------------------------------------

server/package.json

{
  "name": "server",
  "version": "1.0.0",
  "description": "",
  "main": "server.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "node server.js"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "express": "^4.16.3",
    "socket.io": "^2.1.1"
  }
}

----------------------------------------

server.js

const express = require('express');
const socket = require('socket.io');

const app = express();

//server entry port
const port = 5000;

server = app.listen(port, function(){
    console.log('server is running on port ', port)
});

let clientNum = 0;

io = socket(server);

io.on('connection', (socket) => {
    
    clientNum++;
    let currentTime = new Date();
    const socketId = socket.id;

    const connectionRes = currentTime.toLocaleString() + ' ' + 
      socketId + ' connected. ' +clientNum.toString() + ' online'; 

    console.log(connectionRes);

    //send to self when connected
    io.to(socketId).emit('server_connect', connectionRes);

    //response to client send event
    socket.on('client_chat', data=>{
        currentTime = new Date();

        //send to all clients
        //io.emit('server', 'server response');

        //send to everyone except self
        socket.broadcast.emit('server_chat', 
          {
            name: data.name==''? socketId.toString() : data.name,
            message: data.message,
          });

    })

    //client leaves 
    socket.on('disconnect', () => {
      clientNum--;
      currentTime = new Date();

      console.log(currentTime.toLocaleString(), 
        'client disconnected. users', clientNum);
    })

});

---------------------------------------

app.js

import React, { Component } from 'react';
import './App.css';
import io from 'socket.io-client'

class App extends Component {
  constructor(props) {
    super(props)
    
    this.state={
      connectionStatus: '',
      chat: [],
      name: '',
      message: '',
    }

    //connect to server
    this.socket = io('localhost:5000')

    this.socket.on('server_connect', data=>{
      this.setState({connectionStatus: data});
    });

    //append received message to chat
    this.socket.on('server_chat', data=>{
      this.setState(prev=>
        {
          const newChat = <div>
            <span style={{color: 'blue'}}>{data.name}</span>
            <span>: {data.message}</span>
          </div>

          return {
            chat: [...prev.chat].concat(newChat),
          }
      });
    });
  }

  send=()=>{ 

    this.socket.emit('client_chat', {
      name: this.state.name,
      message: this.state.message,
    });

    //append my message to chat
    this.setState(prev=>
      {
        const newChat = <div>
          <span style={{color: 'green'}}>me</span>
          <span>: {this.state.message}</span>
        </div>

        return {
          chat: [...prev.chat].concat(newChat),
        }
    });
  }

  changeName=(e)=>{
    this.setState({name: e.target.value});
  }

  changeMessage=(e)=>{
    this.setState({message: e.target.value});
  }

  componentDidMount(){
    console.log(JSON.stringify(process.env));
  }

  render() {

    const chatDialog = this.state.chat.map((item,index)=>{
      return <div key={index}>{item}</div>
    })

    return (
      <div>
        {this.state.connectionStatus} <br/>

        <div style={{height:'300px',
                 backgroundColor:'lightGrey',
                 overflow:'scroll'}}>
          {chatDialog}
        </div>

        <input placeholder='Name'
          onChange={(e)=>this.changeName(e)}></input>
        <br/>
        <textarea style={{width:'350px', height:'100px'}} placeholder='Message'
          onChange={(e)=>this.changeMessage(e)}></textarea>
        <br/>
        <button onClick={()=>this.send()}>send</button>
      </div>
    );
  }
}

export default App;

--------------------------------------------
reference:

Saturday, 29 September 2018

譚艷---光明

socket.io


reference:
https://www.youtube.com/watch?v=FvArk8-qgCk&list=PL4cUxeGkcC9i4V-_ZVwLmOusj8YAUhj_9&index=5
https://www.youtube.com/watch?v=tHbCkikFfDE&t=1909s
https://codeburst.io/isomorphic-web-app-react-js-express-socket-io-e2f03a469cd3
https://blog.cloudboost.io/creating-a-chat-web-app-using-express-js-react-js-socket-io-1b01100a8ea5

broadcast to single client
https://socket.io/docs/rooms-and-namespaces/
https://stackoverflow.com/questions/11484418/socket-io-broadcast-to-certain-users

Deploying Node.js and Socket.io App to Heroku
http://robdodson.me/deploying-your-first-node-dot-js-and-socket-dot-io-app-to-heroku/
https://devcenter.heroku.com/articles/node-websockets

Connecting to a specific Server Ip with Socket.io
https://stackoverflow.com/questions/22915149/connecting-to-a-specific-server-ip-with-socket-io

Get static IP address for Heroku app
https://serverfault.com/questions/871875/get-static-ip-address-for-heroku-app/871878
https://devcenter.heroku.com/articles/fixie

WebSockets vs REST
https://www.pubnub.com/blog/2015-01-05-websockets-vs-rest-api-understanding-the-difference/

start server and client simultaneously from 1 command window
https://stackoverflow.com/questions/30950032/how-can-i-run-multiple-npm-scripts-in-parallel

Use a package called concurrently.
npm i concurrently --save-dev
Then setup your npm run dev task as so:
"dev": "concurrently --kill-others \"npm run start-watch\" \"npm run wp-server\""

react social media login

project linkhttps://chuanshuoge1-socialmedialogin.herokuapp.com/

facebook & google login button

logged in, got access token

to log out, clear website data

add google+ api -> add authorized origins

facebook developer -> add domain



package.json

{
  "name": "react-facebook-login",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "react": "^16.5.2",
    "react-dom": "^16.5.2",
    "react-facebook-login": "^4.1.0",
    "react-google-login": "^3.2.1",
    "react-scripts": "1.1.5"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test --env=jsdom",
    "eject": "react-scripts eject"
  }
}

-----------------------------------------------

app.js

import React, { Component } from 'react';
import './App.css';

import Facebook from './components/facebook';
import Google from './components/google';

class App extends Component {

  render() {
    return (
      <div>     
        <Facebook/><br/>
        <Google/><br/>
        To log out, clear webbroweser saved website data
      </div>
    );
  }
}

export default App;

---------------------------------------------

google.js

import React, {Component} from 'react'
import { GoogleLogin} from 'react-google-login';

export default class Google extends Component{
    state={
        isLoggedIn: false,
        userID:'',
        name:'',
        email:'',
        picture:'',
        accessToken:''
    }

  

    handle_loginSuccess = (res) =>{

        this.setState({
            isLoggedIn:true,
            userID: res.profileObj.googleId,
            name: res.profileObj.name,
            email:res.profileObj.email,
            picture:res.profileObj.imageUrl,
            accessToken: res.accessToken
        })
    }

    handle_loginFail=(res)=>{
        console.log(res);
    }
       
      render(){
        let googleContent;

        if(!this.state.isLoggedIn){

            googleContent=(<GoogleLogin
                clientId="777285939272-s9bsmvkvve3jidsho0qspb928r6avdq5.apps.googleusercontent.com"
                buttonText="Login with Google"
                onSuccess={this.handle_loginSuccess}
                onFailure={this.handle_loginFail}
            />)}else{

            googleContent=(<div>

                <div style={{
                    width:'400px',
                    margin:'auto',
                    background:'#f4f4f4',
                    overflow: 'scroll'
                }}>

                    <img src={this.state.picture} alt={this.state.name}/>
                    <h2>Welcome {this.state.name}</h2>
                    <p>Email: {this.state.email}</p> 
                    Access Token: {this.state.accessToken}
                </div>
            </div>);
            }
        
        return(
            <div>{googleContent}</div>
        )
      }
}

---------------------------------------

facebook.js

import React, {Component} from 'react'
import FacebookLogin from 'react-facebook-login';

export default class Facebook extends Component{
    state={
        isLoggedIn: false,
        userID:'',
        name:'',
        email:'',
        picture:'',
        accessToken:''
    }

    componentClicked=()=>console.log('clicked');

    responseFacebook=res=>{

        this.setState({
            isLoggedIn:true,
            userID: res.userID,
            name: res.name,
            email:res.email,
            picture:res.picture.data.url,
            accessToken:res.accessToken
        })
    }

    render(){
        let fbContent;

        if(this.state.isLoggedIn){
            fbContent= (
                <div style={{
                    width:'400px',
                    margin:'auto',
                    background:'#f4f4f4',
                    overflow: 'scroll'
                }}>

                    <img src={this.state.picture} alt={this.state.name}/>
                    <h2>Welcome {this.state.name}</h2>
                    <p>Email: {this.state.email}</p>
                    Access Token: {this.state.accessToken}
                </div>
            );
        }else{
            fbContent=(<FacebookLogin
                appId="290235811581073"
                autoLoad={false}
                fields="name,email,picture"
                onClick={this.componentClicked}
                callback={this.responseFacebook} />)
        }

        return(
            <div>
                {fbContent}
            </div>
        )
    }
}

----------------------------------------------

.env

HTTPS=true

------------------------------------------------
reference: