1. 程式人生 > 其它 >簡單聊天室

簡單聊天室

演示

html

<div id="firstStep">
    <input type="text" placeholder="輸入使用者名稱" id="username"/>
    <button id="inter">進入聊天室</button>
    <div id="message" style="color:red"></div>
</div>
<div id="secondStep" style="display: none;">
    <div id="infobox" class="infobox">
        <span id="upButton">&#8593</span>
    </div>
    <input type="text" id="input" placeholder="輸入資訊..."/>
    <button id="send">傳送</button>
    <div id="message2" style="color:red"></div>
    <p id="userHeader"></p>
</div>

JS

const input=document.getElementById('input')
const send=document.getElementById('send')
const infobox=document.getElementById('infobox')
const inter=document.getElementById('inter')
const username=document.getElementById('username')
const color=['#45C195','#C5517D','#C4904E','#B5CD69','#4E91C4','#B364CB','#C8B35D','#3AADAA','#8A40BE','#C24C8B']
const upButton=document.getElementById('upButton')


// 使用者名稱稱與字型顏色
let name
let textColor


// 型別
const TYPE_ENTER=0
const TYPE_MSG=1
const TYPE_CLOSE=2

// socket
let socket

inter.addEventListener('click',()=>{
    // 01 設定使用者名稱
    if(username.value===''){
        document.getElementById('message').innerHTML='請輸入使用者名稱!'
        return
    }
    name=username.value
    document.getElementById('userHeader').innerHTML='使用者:'+name

    // 02 為使用者設定顏色
    textColor=color[Math.floor(Math.random()*10)]

    // 03 切換顯示
    const firstStep=document.getElementById('firstStep')
    const secondStep=document.getElementById('secondStep')
    firstStep.style.display='none'
    secondStep.style.display='block'

    // 04 進入聊天室
    socket = new WebSocket('ws://localhost:8001');
    socket.addEventListener('open', function (event) {
        let userInfo={
            username:name,
            type:TYPE_ENTER,
        }
        socket.send(JSON.stringify(userInfo));
    });

    // 05 接受資訊
    socket.addEventListener('message', function (event) {
        const data=JSON.parse(event.data)

        let div = document.createElement('div');
        div.innerHTML = data.msg

        if(data.type===TYPE_ENTER||data.type===TYPE_CLOSE){
            div.style.color = 'rgb(151 151 151)'
        }else{
            div.style.color = data.color
        }

        let span=document.createElement('span')
        span.innerHTML='-----'+new Date().toLocaleTimeString()
        div.appendChild(span)

        document.getElementById('infobox').appendChild(div)
        infobox.scrollTop=infobox.scrollHeight-infobox.offsetHeight  //儲存檢視在底部
    });

    // 06 傳送資訊
    send.addEventListener('click',()=>{
        sendMessage()
    })
    document.addEventListener('keyup',(e)=>{
        if (e.code === 'Enter') {
            sendMessage()
        }
    })

    upButton.addEventListener('click',()=>{
        infobox.scrollTop=0
    })
})


function sendMessage(){
    const message2=document.getElementById('message2')
    if(input.value===''){
        message2.innerHTML='訊息不能為空'
        return
    }
    message2.innerHTML=''
    
    let userInfo={
        type:TYPE_MSG,
        color:textColor,
        msg:input.value
    }
    socket.send(JSON.stringify(userInfo))
    input.value=''
}

CSS

.infobox{
    padding: 10px;
    border: 1px solid rgb(186, 183, 183);
    width: 500px;
    height: 200px;
    margin-bottom: 10px;
    overflow: auto;
    box-sizing: border-box;
    position: relative;
}
#upButton{
    width: 30px;
    height: 30px;
    position: fixed;
    background-color: #eee;
    top: 165px;
    border-radius: 15px;
    display: flex;
    justify-content: center;
    align-items: center;
    font-size: 20px;
    cursor: pointer;
    left: 450px;
}

伺服器

npm i nodejs-websocket
// app.js
var ws = require("nodejs-websocket")
const TYPE_ENTER=0
const TYPE_MSG=1
const TYPE_CLOSE=2

var server = ws.createServer(function (connection) {
    
    connection.on("text", function (data) {
        const info=JSON.parse(data)
        if(info.type===TYPE_ENTER){
            connection.username=info.username	// 每個連線有個使用者名稱
            const msg=connection.username+'進入聊天室'  
            broadcast(JSON.stringify({  		// 廣播資訊
                msg,
                type:TYPE_ENTER
            }))
        }else if(info.type===TYPE_MSG){
            const msg=connection.username+':'+info.msg
            broadcast(JSON.stringify({
                msg,
                type:TYPE_MSG,
                color:info.color
            }))
        }
    })

    connection.on("close", function (code, reason) {
        const msg=connection.username+'離開聊天室'
        broadcast(JSON.stringify({
            msg,
            type:TYPE_CLOSE
        }))
    })

    connection.on('error',(err)=>{
        console.log('異常:',err)
    })
}).listen(8001)

function broadcast(msg){
    server.connections.forEach(item=>{
        item.send(msg)
    })
}
node app.js