$ yum install gcc gcc-c++ $ yum install openssl-devel make $ wget http://nodejs.org/dist/v0.10.31/node-v0.10.31.tar.gz ※ http://nodejs.org/download/ 최신버젼받기 $ tar xvfz node-v0.10.31.tar.gz $ cd node-v0.10.31 $ ./configure --prefix=/data/nodejs { 'target_defaults': { 'cflags': [], 'default_configuration': 'Release', 'defines': [], 'include_dirs': [], 'libraries': []}, 'variables': { 'clang': 0, 'gcc_version': 44, 'host_arch': 'x64', 'node_install_npm': 'true', 'node_prefix': '/data/nodejs', 'node_shared_cares': 'false', 'node_shared_http_parser': 'false', 'node_shared_libuv': 'false', 'node_shared_openssl': 'false', 'node_shared_v8': 'false', 'node_shared_zlib': 'false', 'node_tag': '', 'node_unsafe_optimizations': 0, 'node_use_dtrace': 'false', 'node_use_etw': 'false', 'node_use_openssl': 'true', 'node_use_perfctr': 'false', 'node_use_systemtap': 'false', 'python': '/usr/bin/python', 'target_arch': 'x64', 'v8_enable_gdbjit': 0, 'v8_no_strict_aliasing': 1, 'v8_use_snapshot': 'true', 'want_separate_host_toolset': 0}} creating ./config.gypi creating ./config.mk $ make && make install ##### bin Path는 계정 및 shell환경에 맞게 profile 에 등록하기## $ vi /root/.bash_profile PATH=$PATH:$HOME/bin PATH=$PATH:/data/nodejs/bin ##nodjs bin등록 export PATH source /root/.bash_profile ############################################################## $ /data/nodejs/bin/node -v v0.10.31 ## npm 이용한 forever 데몬프로그램 설치######################## $ /data/nodejs/bin/npm install -g forever ## npm 이용한 socket.io 설치################################### $ /data/nodejs/bin/npm install -g socket.io
'Programming'에 해당되는 글 69건
- 2014.09.15 [node.js] 리눅스 centos 소스설치
- 2014.09.15 [node.js] 채팅프로그램 간단한 샘플만들기
- 2014.09.13 [node.js] express.js 샘플
- 2014.09.12 [node.js] Global Objects Variables 정보
- 2014.09.11 [jQuery] 테이블 UI 플러그인 tablesorter
- 2014.09.04 [PHP] Anonymous functions 익명함수
- 2014.08.21 테이블 sort 처리 하는 jquery 플러그인(jquery tablesorter)
- 2014.07.31 TOMCAT Jconsole와 Jvisualvm을 이용한 JMX 모니터링 셋팅
- 2014.06.25 [SPRING] 서버환경(개발/운영)에 따른 설정파일 관리
- 2014.06.24 [SPRING] RequestMapping RequestParam UTF-8(한글) encoding(인코딩) 문제
Node.js 책 잠시 보고 만든 샘플입니다.
그냥 참고용으로!!ㅎㅎ
1. Server Side Node.js Socket.io
- var io = require('socket.io').listen(80);
- var clients = {};
- io.sockets.on('connection', function (socket){
- //입장 및 닉네임체크
- socket.on('create_nickname',function(nickname,returnFunction){
- //닉네임중복체크
- var returnCode = 1;
- for ( var i in clients ){
- if ( clients[i] == nickname ){
- returnCode = -1;
- break;
- }
- }
- //닉네임체크확인 결과 전달
- returnFunction(returnCode);
- //닉네임체크 유효화됨
- if ( returnCode == 1 ) {
- //클라이언트 닉네임등록
- clients[socket.id] = nickname;
- //새접속자로인한 전체 유저리스트 전달함
- io.sockets.emit('user_list',clients);
- //전체유저 메세지전송
- io.sockets.emit('msgPush',{"nickname":"시스템","msg":clients[socket.id]+" 유저가 입장하셨습니다."});
- console.log('CONNECT : ',nickname+' ['+socket.id+'] '+'('+Object.keys(clients).length+'명)');
- }
- });
- socket.on('msgSend',function(data){
- //자신을 제외한 전체유저에게 메세지전송
- socket.broadcast.emit('msgPush',data);
- /*
- *socket.emit('msgPush',data);//자신에게만 보낼때
- *socket.broadcast.emit('msgPush',data);//자신제외 전체유저
- *io.sockets.emit('msgPush',data);//자신포함 전체유저에게
- *io.sockets.in(socket_id).emit('msgPush',data);//특정유저에게 귓속말시 socket_id추가입력하면됨
- *io.of('namespace').emit('msgPush', data); //of 지정된 name space의 유저
- */
- console.log('Chat Msg : ','['+data['nickname']+'] '+data['msg']);
- });
- //접속종료시처리
- socket.on('disconnect', function(){
- if ( clients[socket.id] ){
- //유저이탈 메세지전달
- io.sockets.emit('msgPush',{"nickname":"시스템","msg":clients[socket.id]+" 유저가 나가셨습니다."});
- console.log('DISCONNECT : ', clients[socket.id]);
- //이탈유저닉네임삭제
- delete clients[socket.id];
- //유저이탈 전체유저리스트 갱신
- io.sockets.emit('user_list',clients);
- }else{
- console.log('NOT USER DISCONNECT : ', socket.id);
- }
- });
- });
2. Client
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="UTF-8">
- <title>Chat</title>
- </head>
- <body>
- <div id="chatJoin">
- <form id="chatJoinForm">
- 대화명 : <input id="nickname" name="nickname" type="text"> <input type="submit" value="입장">
- </form>
- </div>
- <div id="chatRoom" style="display:none;">
- <div id="msgList" style="float:left;width:500px;height:300px;border:1px solid #1D365D;overflow:auto;"></div>
- <div style="float:left;width:100px;height:300px;border:1px solid #1D365D;margin-left:3px;">
- <div style="border-bottom:1px solid #1D365D;">접속자</div>
- <div id="userList"></div>
- </div>
- <div style="clear:both;">
- <form id="chatMsgForm">ChatMsg : <input id="msgText" name="msg" type="text"> <input type="submit" value="전송"></form>
- </div>
- </div>
- </body>
- <script type="text/javascript" src="jquery-1.11.1.min.js"></script>
- <script type="text/javascript" src="socket.io.js"></script>
- <script type="text/javascript">
- $(function(){
- var socket;
- function createNickname(nickName){
- socket.emit('create_nickname',nickName,function(returnCode){
- if ( returnCode == 1 ){
- //정상적인 닉네임
- $('#chatJoin').hide();
- $('#chatRoom').show();
- $('#msgText').focus();
- }else{ //아니면 닉네임중복됨
- alert('존재하는 닉네임입니다.');
- $('#nickname').focus();
- socket.disconnect();
- }
- });
- }
- function msgAdd(data){
- var sHtml = '<div><span style="color:blue;">'+data['nickname']+'</span> : '+data['msg']+'</div>';
- $('#msgList').append(sHtml);
- $("#msgList").scrollTop($("#msgList")[0].scrollHeight);
- }
- $('#chatMsgForm').submit(function(event){
- event.preventDefault();
- var data = {"nickname":$('#nickname').val(),"msg":$('#msgText').val()}
- msgAdd(data);
- $('#msgText').val('');
- $('#msgText').focus();
- //서버에 입력메세지전달
- socket.emit('msgSend', data);
- });
- $('#chatJoinForm').submit(function(event){
- event.preventDefault();
- if ( !$('#nickname').val() ){
- alert("닉네임을 입력해주세요");
- $('#nickname').focus();
- return false;
- }
- /*
- *https://github.com/automattic/socket.io-client
- */
- socket = io.connect('http://127.0.0.1', {'forceNew':true,reconnection:false});
- socket.on('connect', function () {
- createNickname($('#nickname').val());
- });
- socket.on('user_list',function(clients){
- //심플테스트 버젼이라서 삭제하고 새로 갱신하는방안
- $('#userList').html('');
- for ( var i in clients ){
- if ( clients[i] == $('#nickname').val() ){
- sHtml = '<div style="font-weight:bold;">'+clients[i]+'</div>';
- }else{
- sHtml = '<div>'+clients[i]+'</div>';
- }
- $('#userList').append(sHtml);
- }
- });
- socket.on('msgPush',function(data){
- msgAdd(data);
- });
- socket.on('disconnect', function(){
- $('#msgList').html('');
- $('#nickname').val('');
- $('#chatJoin').show();
- $('#chatRoom').hide();
- alert('Server Disconnect');
- });
- socket.on('connect_error', function (data) {
- alert('CONNECT_ERROR : '+data);
- });
- });
- });
- </script>
- </html>
메뉴얼 사이트
- Application : http://expressjs.com/api.html#express
- Request : http://expressjs.com/api.html#req.params
- Response : http://expressjs.com/api.html#res.status
- Router : http://expressjs.com/api.html#router
- Middleware : http://expressjs.com/api.html#middleware.api
테스트 샘플자료 (자세한 내용은 위에 API 참조하면 방대함 정규식처리등 많음)
- var express = require('express'), http = require('http');
- var bodyParser = require('body-parser');
- var app = express();
- app.use(bodyParser());
- app.all('*', function( req, res, next){
- res.writeHead(200,{
- "Content-Type" : "text/plain"
- });
- next();
- });
- app.get("/", function( req, res){
- res.end("HOME DIR : /");
- });
- app.get("/test", function( req, res){
- res.end("HOME DIR : /test");
- });
- app.get("/params/:user", function( req, res){
- var sText = " Params : "+req.params.user; // OR req.param('user')
- sText += "\n GET : "+req.query.q; //search?q=test OR req.param('q')
- sText += "\n POST : "+req.param('name'); //POST name=tobi
- //sText += "Cookie : "+req.cookies.name; // Cookie: name=tj
- sText += "\n ip : "+req.ip; // req.ips When "trust proxy" is `true`, parse the "X-Forwarded-For"
- res.end(sText);
- });
- app.get("*", function( req, res){
- res.end("NOT PAGE");
- });
- http.createServer(app).listen(80, '127.0.0.1');
- console.log('HTTP URL : http://127.0.0.1:80/');
자세한 내용은 메뉴얼 참조 : http://nodejs.org/api/globals.html#globals_global
Global Objects
- global
- process
- console
- Class: Buffer
- require()
- require.resolve()
- require.cache
- require.extensions
- __filename
- __dirname
- module
- exports
- setTimeout(cb, ms)
- clearTimeout(t)
- setInterval(cb, ms)
- clearInterval(t)
변수류
__filename : 실행중인 경로포함 파일이름
__dirname : 실행중인 파일 경로까지만
실행한 Process 정보
- http://nodejs.org/api/process.html#process_process_versions
jQuery Table Plugin 괜찮은 것 소개
메뉴얼 : http://mottie.github.io/tablesorter/docs/index.html
데모 : http://mottie.github.io/tablesorter/docs/index.html#Demo
tablesorter Bootstrap LESS theme 도 지원함
아래 샘플 보면 row 추가삭제에 대한 설명이나 페이징에 대한 설명도 잘 나와있다.
샘플설명자료 : http://mottie.github.io/tablesorter/docs/index.html#Examples
그리고 다양한 추가 플로그인 존재하여서 관리툴 개발시 상당히 유용함
Plugins / Widgets
† these widgets are included in the jquery.tablesorter.widgets.js
file (except for extra filter formatter functions)
‡ this widget is included with the plugin core.
- Beta Align Character Widget (v2.15.8).
- Build Table Widget (v2.11; Updated v2.16).
- † Columns Highlight widget (v2.0.17)
- Beta Column Selector widget (v2.15; Updated v2.17.0).
- Content Editable widget (v2.9; v2.13.2).
- † Filter Widget (Updated v2.17.4):
- basic (v2.0.18; Updated v2.17.5)
- external option (match any column) (v2.13.3; v2.15)
- external inputs (v2.14; v2.15)
- custom (v2.3.6; v2.10.1)
- custom searches (New v2.17.5)
- formatter: jQuery UI widgets and HTML5 Elements (v2.7.7; Updated v2.17.5).
- formatter: select2 (New v2.16.0; Updated v2.17.5)
- Grouping rows widget:
- basic (v2.8; v2.15).
- Grouping + filter + child rows (v2.15.12)
- Header titles widget (v2.15.6; 2.15.7)
- Beta Math widget (New v2.16; Updated v2.17.0).
- Beta Output widget (New v2.16; Updated v2.17.5)
- Pager plugin (basic & ajax demos; Updated v2.17.5).
- Pager widget (basic & ajax demos) (v2.12; Updated v2.17.5).
- Beta Print widget (New v2.16.4; Updated v2.17.2)
- Beta Reflow widget (New v2.16)
- Repeat Headers widget (v2.0.5; v2.9)
- † Resizable Columns widget (v2.0.23.1; Updated v2.17.4)
- † Save sort widget (v2.0.27)
- Scroller widget (v2.9; Updated v2.17.3).
- Beta StaticRow widget (New v2.16; Updated v2.17.3).
- † Sticky header widget (v2.0.21.1; Updated v2.16.2)
- Sticky header (css3) widget (v2.14.2; Updated v2.16.4).
- † UITheme widget (Updated v2.17.4):
- jQuery UI theme (v2.0.9)
- Bootstrap (v2.4)
- ‡ Zebra stripe widget
Anonymous functions - http://php.net/manual/ro/functions.anonymous.php
있다는 것만 알지.. 사용하지 않았다..
그런데 구글링 중 괜찮은 활용 방법을 찾아서!! 왠지 jquery 하는듯한 느낌은 뭐지...;;
- 특정 배열값 파싱하거나 재구성할때 for문 안돌리고 array_map 이용할때 괜찮은듯함.
- <?php
- # your array
- $slike = array('1.jpg','253455.jpg','32.jpg','477.jpg');
- # if you have PHP >= 5.3, I'd use this
- $slike = array_map(function($e){
- return pathinfo($e, PATHINFO_FILENAME);
- }, $slike);
- # if you have PHP <= 5.2, use this
- $slike = array_map('pathinfo', $slike, array_fill(
- 0, count($slike), PATHINFO_FILENAME
- ));
- # dump
- print_r($slike);
- Array
- (
- [0] => 1
- [1] => 253455
- [2] => 32
- [3] => 477
- )
- */
- ?>
※ 단 PHP 5.3 이상부터 가능함!
※ Jquery용 tablesorter
http://mottie.github.io/tablesorter/docs/index.html
※ 설명가이드가 상당히 잘되어있음(페이징설명되어있음)
http://mottie.github.io/tablesorter/docs/index.html#Demo
http://mottie.github.io/tablesorter/docs/index.html#Examples
※ 부스트랩테마도 지원
http://mottie.github.io/tablesorter/docs/example-widget-bootstrap-theme.html
서버 환경
CentOS 6.5
TOMCAT 7
java version "1.7.0_55"
1. 간단하게 vi catalina.sh 또는 vi setenv.sh 설정함
----------------------------------------
CATALINA_OPTS="$CATALINA_OPTS
-Djava.rmi.server.hostname=xxx.xxx.xxx.xxx
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=9080
-Dcom.sun.management.jmxremote.rmi.port=9081
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false"
----------------------------------------
2. 인증 방식 넣기 (설정시 access,password파일 추가등록)
------------------------------------------------
CATALINA_OPTS="$CATALINA_OPTS
-Djava.rmi.server.hostname=xxx.xxx.xxx.xxx
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.port=9080
-Dcom.sun.management.jmxremote.rmi.port=9081
-Dcom.sun.management.jmxremote.authenticate=true
-Dcom.sun.management.jmxremote.access.file=$CATALINA_HOME/conf/jmxremote.access
-Dcom.sun.management.jmxremote.password.file=$CATALINA_HOME/conf/jmxremote.password
------------------------------------------------
※ 계정등록 ( 구글링해보니까 LDAP 연동 방법도 있는 듯 필요시 구글링해볼것!! )
vi jmxremote.access ( 계정에 맞게 readonly 또는 readwrite )
------------------------------------------------
admin readwrite \
create javax.management.moitor.*,javax.management.timer.* \
unregister
------------------------------------------------
vi jmxremote.password
------------------------------------------------
admin password
------------------------------------------------
3. 에러발생시 처리 방안
※ Error: Exception thrown by the agent : java.net.MalformedURLException: Local host name unknown: java.net.UnknownHostException: dev-was01: dev-was01: Name or service not known
=> vi /etc/hosts 아래 host 추가하면됨
127.0.0.1 localhost dev-was01
※ shutdown시 Error: Exception thrown by the agent : java.lang.NullPointerException
=> CATALINA_OPTS 아닌 JAVA_OPTS 에 넣으면 Exception 에러발생
=> http://archive.apache.org/dist/tomcat/tomcat-7/v7.0.53/bin/extras/
4. Apache 메뉴얼 listener was configured in server.xml 추가하는 방법
URL : http://tomcat.apache.org/tomcat-7.0-doc/config/listeners.html
Attribute | Description |
---|---|
rmiRegistryPortPlatform | The port to be used by the JMX/RMI registry for the Platform MBeans. This replaces the use of the |
rmiServerPortPlatform | The port to be used by the Platform JMX/RMI server. |
rmiBindAddress | The address of the interface to be used by JMX/RMI server. This option is incompatible with setting the system property |
useLocalPorts | Should any clients using these ports be forced to use local ports to connect to the the JMX/RMI server. This is useful when tunnelling connections over SSH or similar. Defaults to |
Using file-based Authentication and Authorisation
If this listener was configured in server.xml as:
<Listener className="org.apache.catalina.mbeans.JmxRemoteLifecycleListener"
rmiRegistryPortPlatform="10001" rmiServerPortPlatform="10002" />
with the following system properties set (e.g. in setenv.sh):
-Dcom.sun.management.jmxremote.password.file=$CATALINA_BASE/conf/jmxremote.password
-Dcom.sun.management.jmxremote.access.file=$CATALINA_BASE/conf/jmxremote.access
-Dcom.sun.management.jmxremote.ssl=false
$CATALINA_BASE/conf/jmxremote.password containing:
admin letmein
$CATALINA_BASE/conf/jmxremote.access containing:
admin readwrite
then opening ports 10001 (RMI Registry) and 10002 (JMX/RMI Server) in your firewall would enable jconsole to connect to a Tomcat instance running behind a firewall using a connection string of the form:
service:jmx:rmi://<hostname>:10002/jndi/rmi://<hostname>:10001/jmxrmi
with a user name of admin
and a password of letmein
.
개발후 배포시 war로 압축해서 배포하는 그때
서버환경(개발/운영)에 따라서 DB접근 정보나 기타 cfg 설정이 다른 경우가 있다
그런 경우 PropertyPlaceholderConfigurer등 설정 정보를 다르게 보게 해야되는 데
구글링 해보니까 아래 Stackoverflow 몇가지를 제시하고있다.
그중에 괜찮다고 생각되는 두가지 방안
1. 아래 방법처림 배포될 서버에 예상해서 설정해서 여러개로 구성하는 방법
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="locations"> <list> <value>classpath:your-production-config.properties</value> <value>file:C:/Users/${user.name}/test-application.properties</value> </list> </property> <property name="ignoreUnresolvablePlaceholders" value="true"/> <property name="ignoreResourceNotFound" value="true"/> <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE"/> </bean>
2. ${catalina.home} 변수 이용한 Tomcat 디렉토리의 conf에 설정을 따로 구성해두는 방안
<context:property-placeholder location="file:${catalina.home}/conf/myFirst.properties" ignore-unresolvable="true" /> <context:property-placeholder location="classpath:second.properties" ignore-unresolvable="true" /> <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="locations"> <value>file:${catalina.home}/conf/dbpool.properties</value> </property> </bean>
개발환경에서 한개 서버에 버젼에 따라서 여러 톰캣을 띄워야 할 경우에는 2번 방법이 괜찮은 것 같다.
form / Ajax 통해서 URL or Get 데이터 encodeURIComponent 보낼때에
한글이 제대로 인코딩이 안된다고하면
web.xml에 아래 해당 filter 정보를 입력해준다
그리고 filter-name의 정보를 해당 url pattern에 mapping 해주면된다 servlet에 따라서 mapping 해줄것!!
일반적으로 전체가 다 UTF-8 환경이라면 /* 하면될듯하다.
encodingFilterUTF8 org.springframework.web.filter.CharacterEncodingFilter encoding UTF-8 encodingFilterUTF8 /*