Go web 8. EventSource를 이용한 채팅
EventSource란?
현재의 계속 바뀌는 웹 형태가 요구 됨에 따라 추가된 기술로 WebSocket과 EventSource가 있다.
WebSoket은 양쪽에 소켓을 연결하여 send/receive가 가능한 형태이다. 페이지가 열린 상태에서 서버와 연결을 끊지 않고 데이터를 계속 주고 받을 수 있는 기술
EventSource는 서버가 일방적으로 데이터를 보내기만 하는 일방통행 형태의 기술이다.
EventSource를 이용한 채팅
ex) index.html
<html>
<head>
<title>EventSource Chatting program</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="chat.js"></script>
</head>
<body>
<div id="chat-log"></div>
<dev id="user-name"></dev>
<from id="input-form">
<input type="text" id="cat-msg" size="64" autofocus />
<input type="submit" value= "Send"/>
</from>
</body>
</html>
ex) chat.js
$(function(){
if (!window.EventSource) {
alert("No EventSource!")
return
} //현재 위도우가 이벤트 소스를 지원하는지
var $chatlog = $('#chat-log')
// 채팅로그를 출력할 부분 해당 엘리멘트를 찾아옴
var $chatmsg = $("#chat-msg")
// 채팅 메세지 부분
// 입력 받은 유저네임 확인
var isBlank = function(string){
return string == null || string.trim() === "";
// 스트링이 널 이거나 스트링의 여백을 지운결과가 빈문자열 이면
// === 세개일때 값과 타입까지 비교
};
// 유저 내임 입력 받기
var username;
while (isBlank(username)){
username = prompt("What's your name?");
if(!isBlank(username)) {
$('#user-name').html('<b>' + username + '</b>') ;
}
}
// form 에서 submit했을때 메세지 보내기
$('#input-form').on('submit', function(e){
$.post('/messages', { //jquery의 post라는 펑션
msg: $chatmsg.val(),
name: username
});// username과 msg내용 보냄
$chatmsg.val(""); //빈문자열로 바꾸고
$chatmsg.focus(); // 다시 문자열 입력할 수 있게
return false;
});
// 서버가 이벤트소스르 통해서 알려줄 경우 호출
var addMessage = function(data){
var text = "";
if(!isBlank(data.name)){
// 만약 데이터에 name이 있을 경우
text = '<strong>' + data.name + ':</strong>';
}
text += data.msg // 텍스트에 데이터 메세지 추가
$chatlog.prepend('<div><span>' + text + '</span></dvi>');
};
addMessage({
msg: 'hello',
name: 'aaa'
})
addMessage({
msg: 'hello2',
})
// 이벤트 소스 열기
var es = new EventSource('/stream') // 이벤트 소스 요청 경로
es.onopen = function(e){
$.pos('users/', {
name: username
}); // 이벤트 소스가 열릴떄 유저스로 메세지 전송
}
// 이벤트 소스를 통해서 메세지가 올때 onmessage펑션이 호출
es.onmessage = function(e) { //e 인자로 받아서
var msg = JSON.parse(e.data); // json형태의 메세지
addMessage(msg); // 메세지 추가
};
// 상대방이 나갔을때 표시
window.onbeforeunload = function() {
$.ajax({
url: "/users?username=" + username,
type: "DELETE"
}); // 딜리트 메소드
es.close() // 이벤트 소스 닫기
};
})
ex) main
package main
import (
"encoding/json"
"fmt"
"net/http"
"strconv"
"time"
"github.com/antage/eventsource"
"github.com/gorilla/pat"
"github.com/urfave/negroni"
)
func postMessageHandler(w http.ResponseWriter, r *http.Request) {
msg := r.FormValue("msg")
name := r.FormValue("name")
sendMessage(name, msg) // 메세지 보내기
}
func addUserHandler(w http.ResponseWriter, r *http.Request) {
username := r.FormValue("name")
sendMessage("", fmt.Sprintf("add user: %s", username))
}
func leftUserHandler(w http.ResponseWriter, r *http.Request) {
username := r.FormValue("username")
sendMessage("", fmt.Sprintf("left user: %s", username))
}
type Message struct {
Name string `json:"name"`
Msg string `json:"msg"`
}
var msgCh chan Message
// message를 집어넣는 채널
func sendMessage(name, msg string) {
msgCh <- Message{name, msg}
// sendMessage 가 호출되면 이름과 메세지가 msg채널에 들어감
}
//메세지 채널에서 하나씩 팝해옴
func processMsgCh(es eventsource.EventSource) {
for msg := range msgCh {
data, _ := json.Marshal(msg) //json형태로 마샬
es.SendEventMessage(string(data), "", strconv.Itoa(time.Now().Nanosecond()))
// 메세지와 아이디를
}
}
func main() {
es := eventsource.New(nil, nil) //이벤트 소스 패키지 사용
defer es.Close()
go processMsgCh(es) // go쓰래드로 메세지를 팝해줌
mux := pat.New()
mux.Post("/messages", postMessageHandler)
mux.Handle("/stream", es)
mux.Post("/users", addUserHandler)
mux.Delete("/users", leftUserHandler)
n := negroni.Classic()
n.UseHandler(mux)
//negroni 데코레이터로 먹스핸들러를 감쌈
//기본적으로 퍼블릭 서버를 제공
http.ListenAndServe(":3000", n)
}
Author And Source
이 문제에 관하여(Go web 8. EventSource를 이용한 채팅), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@jinzza456/Go-web-8.-EventSource를-이용한-채팅저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)