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를 동시에 쓰지 못하나요?
동일한 포트가 아니어도 사용불가능인가요?ㅜㅜ
@변종원(웅파)님
답변 감사합니다!!
서버는 어디서 실행된다는게 무슨 뜻인지 이해가 안돼요 ㅜㅜ 아파치 서버 말씀하시는 거면 /opt/apache에 있고, nodejs는 /usr/local/n/ 쪽으로 설치하였습니다. assets/admin/js/node_test.js 이 파일을 구동하려고 합니다. ㅠㅠ
파일을 옮겨도 되는데, 같은 프로젝트 계정 폴더 내에서 관리 되었으면 합니다.
웹소켓 서버는 nodejs 로 만들고, 클라이언트는 CI 로 구성하신건데
먼저 웹소켓 서버를 구동한 후 클라이언트에서 연결을 해당 서버로 하시면 됩니다.
node 서버 구동 방법
$ node node_test.js
- app.listen(3000); // 3000번 포트로 대기중
클라이언트 웹소켓 서버 접속방법
var socket = io.connect('http://localhost:3000'); //웹소켓 서버 연결
@이제다시님
답변 감사합니다!
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 이렇게 뜨네욤 ㅠㅜ
우선 클라이언트에서 접속 시 웹서버가 로컬서버일 경우 localhost 로 접속을 하고
원격지 서버일 경우는 해당하는 원격지의 IP 를 입력하시면 됩니다.
var socket = io.connect('http://원격지IP:3000');
ssl 을 적용하시려면 https 로 접속을 하면 됩니다.
다만 node 웹서버 구동시 ssl 설정을 하여야 합니다.
참고 : https://nodejs.org/api/https.html
@이제다시님
답변 감사합니다!
주신 힌트대로 로컬호스트에서 구동해서 적용해봤는데 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에러가 뜹니다 ㅠㅜ
웹소켓은 브라우저와 웹서버간에 소켓통신을 맺는건데
아래와 같이 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");
@이제다시님
답변 주셔서 정말 감사합니다 ㅠㅠ
현재 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가 뜨구요...
하 ㅠㅠㅠㅠㅠ 정말 막막하네요ㅜㅜ
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/
최대한 자세히 답변 드릴려고 했는데 설명이 어려운거 같아 죄송합니다.
@이제다시님
답변 감사합니다!!
프록시 해제하고 방화벽 열어주니 https://도메인:3000으로 연결이 잘되요 ㅠㅠㅠㅠ 진짜진짜 감사합니다.
답변하시느라 고생하셨어요 정말 ㅜㅜ 정말 감사해요!!