개발 Q&A

제목 CI + socket.io 설치 방법에 대한 문의입니다.
카테고리 서버
글쓴이 뫄뫄잉뿌 작성시각 2018/02/19 17:31:02
댓글 : 10 추천 : 0 스크랩 : 0 조회수 : 13707   RSS

CI를 설치하고, 이 프로젝트 폴더 내에 socket.io를 설치해서 폴더 구조가

- application

- assets

- node_modules

- system

- uploads

- vendor

- 그외 컴포저파일

 

이렇게 있는데..

socket.io 파일을 어디에 만들어서 어떤 경로로 연결해야할지 모르겠습니다. ㅜㅜ

assets/admin/js/node_test.js

node_test.js란 파일을 만들어서 

const app = require('http').createServer(handler)
  , io = require('socket.io').listen(app)
  , fs = require('fs')

app.listen(3000);

function handler (req, res) {
    fs.readFile(__dirname + '/index.html',
    function (err, data) {
        if (err) {
            res.writeHead(500);
            return res.end('Error loading index.html');
        }

        res.writeHead(200);
        res.end(data);
    });
}

io.sockets.on('connection', function (socket) {
   console.log('a user connected with id %s', socket.id);
});

 

이렇게 코드를 넣어주고,

/application/views/admin/header.php 파일에 테스트로 

<script src="https://cdn.socket.io/socket.io-1.4.5.js"></script>
<script>
	
	var socket = io.connect('<?= base_url() ?>assets/admin/js/node_test.js');
	socket.on('news', function (data) {
		console.log(data);
	});

</script>

 

이렇게 해주고 node_test.js를 켜주었습니다.

커넥트를 어떤식으로 연결해야할지 모르겠는데... 같은 도메인을 사용하면서 CI와 nodejs를 동시에 쓰지 못하나요?

동일한 포트가 아니어도 사용불가능인가요?ㅜㅜ

 다음글 DB 갱신시 클라이언트에 알림 보내기 (7)
 이전글 글작성 시 알림에 대한 의견 부탁합니다. (6)

댓글

변종원(웅파) / 2018/02/19 18:20:45 / 추천 0
포트가 달라서 상관없습니다. 서버는 어디서 실행되는건가요? 위 구문은 socket.io 라이브러리를 이용해서 웹소켓에 접속하는 클라이언트입니다.
뫄뫄잉뿌 / 2018/02/20 09:22:58 / 추천 0

@변종원(웅파)님

답변 감사합니다!!

서버는 어디서 실행된다는게 무슨 뜻인지 이해가 안돼요 ㅜㅜ 아파치 서버 말씀하시는 거면 /opt/apache에 있고, nodejs는 /usr/local/n/ 쪽으로 설치하였습니다. assets/admin/js/node_test.js 이 파일을 구동하려고 합니다. ㅠㅠ

파일을 옮겨도 되는데, 같은 프로젝트 계정 폴더 내에서 관리 되었으면 합니다.

이제다시 / 2018/02/20 09:34:49 / 추천 0

웹소켓 서버는 nodejs 로 만들고, 클라이언트는 CI 로 구성하신건데

먼저 웹소켓 서버를 구동한 후 클라이언트에서 연결을 해당 서버로 하시면 됩니다. 

 

node 서버 구동 방법

$ node node_test.js

- app.listen(3000); // 3000번 포트로 대기중

 

클라이언트 웹소켓 서버 접속방법

var socket = io.connect('http://localhost:3000'); //웹소켓 서버 연결

뫄뫄잉뿌 / 2018/02/20 09:49:47 / 추천 0

@이제다시님

답변 감사합니다!

node_test.js가 있는 폴더로 이동하여 node node_test.js로 구동하고,

클라이언트에서 var socket = io.connect('http://localhost:3000');

이걸로 바꾸어보았습니다.

크롬 개발자도구에서 에러 뜬 형태로 보아

Mixed Content: The page at 'https://도메인/modify' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint 'http://localhost:3000/socket.io/?EIO=3&transport=polling&t=M6mnLSD'. This request has been blocked; the content must be served over HTTPS.

현태 홈페이지가 ssl을 적용하여 https로 강제 적용하여 이용중입니다.

혹시나 하여 http://localhost:3000, http:s//localhost:3000, localhost:3000 다 해봤는데

ERR_CONNECTION_REFUSED 이렇게 뜨네욤 ㅠㅜ

이제다시 / 2018/02/20 10:06:06 / 추천 0

우선 클라이언트에서 접속 시 웹서버가 로컬서버일 경우 localhost 로 접속을 하고

원격지 서버일 경우는 해당하는 원격지의 IP 를 입력하시면 됩니다. 

 

var socket = io.connect('http://원격지IP:3000');

 

ssl 을 적용하시려면 https 로 접속을 하면 됩니다. 

다만 node 웹서버 구동시 ssl 설정을 하여야 합니다. 

 

참고 : https://nodejs.org/api/https.html

뫄뫄잉뿌 / 2018/02/20 13:30:26 / 추천 0

@이제다시님

답변 감사합니다!

주신 힌트대로 로컬호스트에서 구동해서 적용해봤는데 ERR_CONNECTION_REFUSED 가 되요 ㅜㅠ 분명 서버 구동중인데..

var socket = io.connect("https://localhost:3000",{secure:true});
	
	socket.emit('test', { my: 'data' });
	
	socket.on('news', function (data) {
		console.log(data);
	});

클라이언트 쪽에서 이렇게 호출하고 

var fs = require( 'fs' );
var app = require('express')();
var https        = require('https');
//var url = require('url');

var io = require('socket.io').listen(server);

var server = https.createServer({ 
	key: fs.readFileSync('/etc/letsencrypt/live/도메인/privkey.pem'), 
	cert: fs.readFileSync('/etc/letsencrypt/live/도메인/cert.pem'), 
	ca: fs.readFileSync('/etc/letsencrypt/live/도메인/chain.pem'), 
},app); 

server.listen(3000, (req, res)=>{ 
	//console.log(req.url);
    console.log('Server is running...');
});

io.sockets.on('connection', function (socket) {
   console.log('a user connected with id %s', socket.id);
   
	sockets.on('news',function(data){
		console.log('good1');
	});
	
	sockets.on('test',function(data){
		console.log('good2');
		socket.emit('news', { my: 'data1' });
	});
});

이렇게 서버단을 구현하였습니다.

아파치 httpd-ssl.conf에 프록시 설정을 

ProxyPass /nodejs_socket/ https://localhost:3000/
ProxyPassReverse /nodejs_socket/ https://도메인:3000/

이렇게 해주었습니다.

ssl 키 파일들도 잘 불러와서 서버 구동때 문제없이 Server is running...이라는 문구가 뜨는데,

클라이언트 쪽에서 호출할 때 ERR_CONNECTION_REFUSED에러가 뜹니다 ㅠㅜ

이제다시 / 2018/02/20 16:19:54 / 추천 0

웹소켓은 브라우저와 웹서버간에 소켓통신을 맺는건데 

아래와 같이 localhost 로 접속을 한다면 본인의 로컬PC 의 3000번 포트로 연결됩니다. 

var socket = io.connect("https://localhost:3000",{secure:true});

 

위와 같이 설정하는 것은 로컬개발환경에서 웹소켓 서버를 본인의 로컬에 띄었을 경우 설정합니다. 

 

원격지에 웹소켓서버가 있을 경우 원격지의 IP 혹은 원격지의 도메인을 입력하시면 됩니다. 

var socket = io.connect("https://원격지IP:3000");

{secure:true} 해당옵션은 보안 웹소켓 접속(wss://) 시 사용하므로 제거 하셔야 합니다.

URL 을 자동으로 인식하여 보안접속 합니다. 

 

ProxyPass 는 웹서버에서 해당폴더로 들어왔을 경우 이동시키는 옵션인데

http://도메인/nodejs_socket 으로 접속했을 경우 서버의 3000번 포트로 이동하는 의미 입니다. 

 

위와같을 경우 웹소켓 접속을 아래와 같이해도 무관합니다. 

var socket = io.connect("https://도메인/nodejs_socket");

 

 

뫄뫄잉뿌 / 2018/02/20 16:56:00 / 추천 0

@이제다시님

답변 주셔서 정말 감사합니다 ㅠㅠ

현재 SSH를 사용하여 원격서버에 접속해서 사용중이고, 해당 서버에 웹 프로젝트가 있어서 동일 IP 서버 내에 위치하고 있습니다. 

이 상황에서 SSH로 연결된 서버내, /home/test/에서 서버를 구동시켰습니다.

/home/test에는 CI와 node_modules폴더들이 있습니다.

말씀해주신대로 https://도메인/nodejs_socket으로 시도해보니 No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://int.dnew.co.kr' is therefore not allowed access. The response had HTTP status code 404. 란 에러가 떠서

node_test.js에 

app.use(function (req, res, next) {
	
	var allowedOrigins = ['https://도메인', 'http://도메인'];
	var origin = req.headers.origin;
	if(allowedOrigins.indexOf(origin) > -1){
		res.setHeader('Access-Control-Allow-Origin', origin);
	}
	
    // Request methods you wish to allow
    res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');

    // Request headers you wish to allow
    res.setHeader('Access-Control-Allow-Headers', '*');

    // Set to true if you need the website to include cookies in the requests sent
    // to the API (e.g. in case you use sessions)
    res.setHeader('Access-Control-Allow-Credentials', true);

    // Pass to next layer of middleware
    return next();
});

을 추가해주었습니다. 이렇게 하고 재시도 해보니 아예 못찾는다고 Not found가 나옵니다 ㅠㅠ

https://localhost/nodejs_socket으로 하면 여전히 ERR_CONNECTION_REFUSED가 뜨구요...

하 ㅠㅠㅠㅠㅠ 정말 막막하네요ㅜㅜ

이제다시 / 2018/02/20 17:17:42 / 추천 0

ProxyPass는 제거 하시고 클라이언트 소스에서 IP 로 접속해보세요

 

var socket = io.connect("https://서버아이피:3000");

ex) var socket = io.connect("https://192.168.0.1:3000"); //웹소켓 서버의 IP를 직접입력

 

nodejs 의 웹서버는 정상적으로 구동되고 포트 Listen 을 3000번으로 설정하셨다면

$ netstat -an | grep LISTEN 으로 포트 열려 있는지 확인하시고

외부에서 telnet IP 3000 등으로 잘 열리는지 확인 하시고 안열렸다면 방화벽을 확인 하세요

 

socket.io 의 기본 튜토리얼 대로만 진행하셔도 잘 되실거 같은데

https://socket.io/get-started/chat/

 

최대한 자세히 답변 드릴려고 했는데 설명이 어려운거 같아 죄송합니다.

 

 

 

 

뫄뫄잉뿌 / 2018/02/20 17:43:15 / 추천 0

@이제다시님

답변 감사합니다!!

프록시 해제하고 방화벽 열어주니 https://도메인:3000으로 연결이 잘되요 ㅠㅠㅠㅠ 진짜진짜 감사합니다.

답변하시느라 고생하셨어요 정말 ㅜㅜ 정말 감사해요!!