ログイン

2016年3月 弊社ホームページは新しくなりました。 https://thinkridge.com

メインメニュー

携帯公式サイト


携帯電話をもっと便利に
もっと楽しく


史上初の吹奏楽専門着メロサイト


POPで癒しでライトでとんがって気持ちのいい〜オルゴール着メロをあなたに

Magome

クラウドベースの MIDI シーケンサ Magome

音楽制作に興味のある方を対象に、スタンドアロンでも使え、ネットならではの面白さも兼ね備えた音楽制作アプリの提供を目指しています

for 携帯電話

https://thinkridge.com/m/
ケータイはこちらへ

2015年11月7日(土曜日)

SNI SSL ってのがけっこう一般的になってきてるみたい

カテゴリー: - takatsuka @ 16時33分22秒

SNI SSL ってのがけっこう一般的になってきてるみたいで、これはかなり良さげな気がしてます。

SSL っていうと IP に紐づけるもんで、いわゆるレンタルサーバーの1サイトで使うみたいなことは事実上不可。
・・・っていうのは、ちょっと前までの話。今はそんなことなさげです。

なので、HTTP じゃ不安だ(=信用ない)から HTTPS にしたい!ってなったら1つのIPを占有できる専用サーバー(今だとVPSとかも)を使うのが定石だったのが、SNI SSL を使えば、レンタルサーバーでも HTTPS のメリットを受諾できます。

DB が使えて、cron が使えて、perl や PHP が使えるレンタルサーバーは全然珍しくないので、そこに SNI SSL を組み合わせれば、実は、Webシステム案件の多くは、証明書代含めても月々千円程度の環境で行けてしまいます。

さらに、レンタルサーバーであれば、OSのパッチあてとかメールのウイルスフィルタ対応とかは、業者様がやってくれ(ることになって)ます。

そのへんも勘案すると実は、保守費用を別にして月々数千円〜1万円以上を覚悟しないといけないと思っていたことは正しくないかもしれません。
ぜひ考慮したいところです。

とはいえ、もちろん、それでも採用出来ないケースはあります。
業者のサーバーに機密情報を置きたくないとか、
ネイティブアプリをサーバーで動かしたいとか、
WindowsXP(のIE) とかガラケーとかは SNI SSL に非対応みたいなので、もしそれら端末からのアクセスを考慮する必要があるときとか。

なにはともあれ、選択肢や可能性が増えることには違いないので、こういう新技術は上手に使っていくことが必要だって感じたと同時に、付いていけるように勉強しなきゃならないと思った次第です。
頑張ります!・・頑張りたい!・・頑張なくてもいい天賦の才がほしい!・・来世に期待しよう!

ありがとうございました。


2015年8月31日(月曜日)

google maps api 表示されなくなってた

カテゴリー: - takatsuka @ 11時45分33秒

ふと数日前くらいからだと思うけど、google maps api の kml layer で、デフォルトのマーカー(赤い下向き矢印っぽいやつ)が表示されてなくなってた。カスタムのマーカーは問題なく表示される。
コードは何も変えていないのになんで?と思って調査。

kml の <iconstyle><color>…</color> が存在するだけで、表示が出来なくなってるようだ。
とはいえコレ、google map でエクスポートした google 様が返してくる kml なんだけど・・。

幸い、使っているサイトは、サーバーを介して kml をクライアントに渡す作りなので、サーバー側で小細工が可能。
というわけで暫定対策として、問題のタグを全削除して出力するようにして対策。
マーカーに色がつかないけど、なにも表示されないよりはいいでしょう。

ただ、原因がまったく不明。ご存じの方おられましたらご助言賜り度。


2015年8月9日(日曜日)

VMware Server から ESXi へ

カテゴリー: - takatsuka @ 12時59分06秒

社内サーバー環境刷新してみました。

これまでは、1台のサーバーPCで、WindowsServer をホストOSにして、VMwareServer1.0 使ってゲストOSを5〜6個動かしておりました。

これはこれでまったく困ってなかったんですが、もう提供すらされてない VMwareServer を使い続けても芸がないかと思い、勉強かねて FreeNAS と ESXi を使った環境に移行してみました。

貧乏性 エコな性分なので、これまでどおり全てを激安サーバー1台で賄うようにして、初期投資と電気代と場所の節約を念頭に置きます。

サーバーPC は FUJITSU MX130 S2。HDD は 1T×2台。ESXi のブート用に8Gの USB メモリ。

  1. ESXi6.0 の ISO イメージをダウンロードして、USBメモリにブート可能な状態として用意。
  2. MX130 S2 に USBメモリを挿し、BIOS で USB ブート可に変更し、ESXi6.0 のインストーラーを起動。
  3. インストール先に、同じUSBメモリを指定しインストール。
    ESXi6.0 は MX130 S2 のデバイスはたぶん全て認識してくれたので、特別なことは何もなくインストール完了。
  4. ESXi 上で FreeNAS9.3 に HDD の 8G くらいを割り当ててインストール。
  5. FreeNAS に、HDD×2 の残りを割り当てる。大体 900G × 2。
  6. FreeNAS 上で、この HDD のミラーのボリュームを作り、iSCSI で共有とする。その際、暗号化をONにして、パスフレーズも設定。
  7. ESXi に戻って、この iSCSI を使ったデータストアを作成。これで、900Gサイズの暗号化されてて RAID1(ミラー)な領域を確保。
  8. これまで稼働させていた各ゲストOSを、VMware vCenter Converer Standalone を使って、上記の領域に持っていって(変換して)完了。

という感じです。

この環境の1番のメリットとしては、FreeNAS のボリュームの中に、各ゲストOSを置くことになるので、特別なハードは不要な上、各ゲストOSに何の細工もナシで、RAID と HDD 暗号化と圧縮の恩恵に預かれるところでしょうか。

HDD 故障に備えた RAID はもちろんですが、昨今の風潮的に、社内サーバーとはいえ泥棒に入られりして HDD を盗まれる可能性も考慮して、暗号化は入れときたいところです。

さらに、暗号化しておけば、HDD を破棄するときの厄介からも解放されます。
データ流出を恐れて HDD にドリルで穴開けるとか、専門業者に高いお金だして消去と廃棄を依頼するとか、かなり手間をかけなければならないところ、何も考えずにそのまま廃棄出来てしまうのはかなりメリットです。

デメリットとしては、FreeNAS がけっこうメモリを食うようなので、そこは奢っとく必要がありますが、ミラーで使う分にはそれほどでもないっぽい気もします。

もうちょっとゴージャスを求めていいんであれば、RAIDZというやつにしてもいいかもです。 HDD が最低3台必要で、メモリも食いますが、すごそうです。

一応、すんなり行かなかったこともあり、ネットで調べたりしたので、備忘録としてあげておきます。情報をあげていらっしゃる方々に感謝です。

  • VPN (ブリッジ) 通信が通らない対策。
    ローカルブリッジ機能を使用するためにはプロミスキャスモードを有効にする必要があるが、ESXi のスイッチがデフォルトで無効になってるので変更する。
    スイッチのセキュリテイタブより「無差別モード」を「承諾」に変更して「OK」をクリック
  • ESXi に WindowsXP,2003 の vSphere Client から接続できない場合の対処
    1. ESXi へ SSH にて接続
      /etc/vmware/rhttpproxy/config.xml を編集

      <vmacore> - <ssl> -

      <cipherList>ALL</cipherList> ←追記

    2. サービスを再起動
      /etc/init.d/rhttpproxy restart
  • VMware vCenter Converer Standalone で変換する際、デフォルトのままだと、元の HDD の設定に関わらず シックプロビジョニング になってしまうので、空き容量に余裕がないときは要設定変更。

これだけ便利でよくできた環境が、たいしてコストかけずに出来てしまうことに感心してしまいますし、優秀なソフトを開発されてる方々に感謝です。

いまどきは、クラウドやら Saas やら VPS やらが充実してますので、社内にサーバーやストレージを置かなきゃいけないようなケースも減ってきているとは思いますが、大量のデータを扱いたいとか、外のサーバーに大事なデータを置いておくのは不安とか、コストの面以外にも、社内に置くメリットはまだあると思います。

一応自分もIT業界の端っこに身を置いてますんで、いろいろな案件に適切な提案をしていけるよう精進しとかんとイカンなと思った次第です。


2015年2月1日(日曜日)

boost::asio で UDPホールパンチング

カテゴリー: - takatsuka @ 22時21分43秒

NAT 越えの技術は skype が出てきたころには話題になってる気がしますが、自前のソフトに組み込んで使えるような標準的な形に既になってるのかよくわからないってこともあり、興味本位で試してみました。

UDP ホールパンチングによる NAT 越えです。
で、boost::asio の udp の勉強も兼ねてサンプルアプリを作ってみました。

とはいえ、boost::asio の udp については難しいことは何もなく tcp よりシンプルに使えました。有難いことです。開発者の方に感謝です。

さて、UDP ホールパンチングについて。
wikipedia みると NAT の実装にはいろいろあるみたいですが、大ざっぱな分類でいう Port-Restricted cone NAT という環境同士までの P2P 通信は実現出来ました。
Full cone NAT とか Address-Restricted cone NAT の環境は試せてないんですが、Port-Restricted より条件緩いものなので、これらもたぶん問題なさそう。

で、Symmetric NAT って言われる環境はやっぱり無理そうでした。

docomo の LTE回線、純正のSPモード と MVNO (nifty の一番安いヤツ) を試しましたが、これに該当してそうです。
スマホのテザリングで繋げた PC で試したので、Symmetric NAT がプロバイダ側にあるのか、スマホのテザリング機能なのか判断できませんが残念。早々に諦めました。

で、以下は自分自身向けの備忘録もかねて、コードの抜粋と、軽く説明を・・。

  • ヘッダ
namespace RLib
{

    class CUdpSocket         :private boost::noncopyable     {         class CSocket;         const boost::shared_ptr<CSocket>    m_spSocket;     public:         CUdpSocket(asio::io_service &ioService);         ~CUdpSocket();         void Close();         bool Bind(unsigned short nPort,boost::system::error_code &ec=boost::system::error_code());         bool Connect(const std::string &sDomain,const std::string &sPort);         bool SendTo(const boost::asio::ip::udp::endpoint &endPoint,                     const boost::shared_ptr<const vector<char>> &spData,                     boost::system::error_code &ec=boost::system::error_code());         bool Send(const boost::shared_ptr<const vector<char>> &spData,                   boost::system::error_code &ec=boost::system::error_code());

        // データ受信         // ・次の読み込み待ちにする場合には Receive(); をコールすべし。コールしない場合には何もしない。         typedef boost::function<void (CUdpSocket &udpSocket,const boost::system::error_code &ec,                                 const boost::asio::ip::udp::endpoint &endPointRemote,                                 const boost::shared_ptr<const vector<char>> &spReceivedData)> FuncOnReceived;         bool Receive(const FuncOnReceived &funcOnReceived,unsigned short nBufferSize=8192);

    public:         static CString GetTextAddress(const asio::ip::udp::socket::endpoint_type &ep)             {                 return CRString::Format(_T("%s:%d"),CString(ep.address().to_string().c_str()),ep.port());             }     };

}

class CUdpHolepunching {     class CMain;     CMain   &m_main; public:     typedef boost::function<void (const CString &s)> FuncMessage;     CUdpHolepunching(const FuncMessage &funcMessage);     ~CUdpHolepunching();

    void Server(unsigned short nPort);     void Client(const std::string &sDomain,const std::string &sPort);

};

  • .cpp
class CUdpSocket::CSocket
{
public:
    CUdpSocket      *m_pUdpSocket;
    ip::udp::socket m_socket;
public:
    CSocket(CUdpSocket &udpSocket,io_service &ioService)
        :m_pUdpSocket(&udpSocket)
        ,m_socket(ioService)
        {
            m_socket.open(ip::udp::v4());
        }
};

CUdpSocket::CUdpSocket(asio::io_service &ioService) :m_spSocket(new CSocket(*this,ioService)) { }

CUdpSocket::~CUdpSocket() {     m_spSocket->m_pUdpSocket = NULL;        // 破棄されたマーク }

void CUdpSocket::Close() {     m_spSocket->m_socket.close(); }

bool CUdpSocket::Bind(unsigned short nPort,boost::system::error_code &ec) {     return m_spSocket->m_socket.bind( ip::udp::endpoint(ip::udp::v4(),nPort), ec ) == false;    // エラーなら }

bool CUdpSocket::Receive(const FuncOnReceived &funcOnReceived,unsigned short nBufferSize) {     struct F{         static void OnReceived(const boost::system::error_code &ec,size_t bytesReceived,                                boost::shared_ptr<CSocket> spSocket,                                boost::shared_ptr<ip::udp::endpoint> spEndpointRemote,                                boost::shared_ptr<vector<char>> spBuffer,const FuncOnReceived funcOnReceived)         {             if( !spSocket->m_pUdpSocket ) return;                       // 破棄されてる?             if( ec ){   // Error                 if( ec == boost::asio::error::operation_aborted ) return;                 //return; エラーでもコールはする             }

            spBuffer->resize(bytesReceived);             if( funcOnReceived ){                 funcOnReceived( *spSocket->m_pUdpSocket, ec, *spEndpointRemote, spBuffer );             }         }     };

    boost::shared_ptr<ip::udp::endpoint> spEndpoint(new ip::udp::endpoint);     boost::shared_ptr<vector<char>> spBuffer(new vector<char>(nBufferSize));    // 受信バッファ     m_spSocket->m_socket.async_receive_from(         asio::buffer(*spBuffer),         *spEndpoint,         boost::bind(             &F::OnReceived,             boost::asio::placeholders::error,             boost::asio::placeholders::bytes_transferred,             m_spSocket,spEndpoint,spBuffer,funcOnReceived)     );

    return true; }

bool CUdpSocket::SendTo(const boost::asio::ip::udp::endpoint &endPoint,                         const boost::shared_ptr<const vector<char>> &spData,boost::system::error_code &ec) {     if( !spData ){         BOOST_ASSERT(false);         return false;     }     const size_t size = m_spSocket->m_socket.send_to( asio::buffer(*spData), endPoint, 0, ec );     if( !ec ) return size == spData->size();     ATLTRACE( _T("nCUdpSocket Error Send -> %s"), CString(ec.message().c_str()) );     return false; }

bool CUdpSocket::Send(const boost::shared_ptr<const vector<char>> &spData,boost::system::error_code &ec) {     if( !spData ){         BOOST_ASSERT(false);         return false;     }     const size_t size = m_spSocket->m_socket.send( asio::buffer(*spData), 0, ec );     if( !ec ) return size == spData->size();     ATLTRACE( _T("nCUdpSocket Error Send -> %s"), CString(ec.message().c_str()) );     return false; }

////////////////////////////////////////////////

class CUdpHolepunching::CMain     :public CWindowImpl<CMain> { public:     DECLARE_WND_CLASS( _T("CMain") );     BEGIN_MSG_MAP(CMain)         MESSAGE_HANDLER(WM_TIMER, OnTimer)     END_MSG_MAP() public:     LRESULT OnTimer(UINT, WPARAM, LPARAM, BOOL&)         {             m_ioService.poll();             return 0;         } public:     const CRUid                 m_id;     FuncMessage                 m_funcMessage;     io_service                  m_ioService;     CUdpSocket                  m_udpSocket;     auto_ptr<deadline_timer>    m_apTimer;

#pragma pack(push,1)     struct CEndpoint     {         unsigned long   m_nIpv4;         unsigned short  m_nPort;         CEndpoint()             {}         CEndpoint(const ip::udp::endpoint &endPoint)             {                 m_nIpv4 = endPoint.address().to_v4().to_ulong();                 m_nPort = endPoint.port();             }     }; #pragma pack(pop)

    std::map<CRUid,CEndpoint>   m_mapMember;

    void OnReceived(CUdpSocket &udpSocket,const boost::system::error_code &ec,                     const boost::asio::ip::udp::endpoint &endPointRemote,                     const boost::shared_ptr<const vector<char>> &spBuffer)         {             if( ec ){   // Error                 m_funcMessage( CRString::Format(_T("%s : OnRecived Error [%s] %s"),                                CString(m_id.GetText().c_str()), CUdpSocket::GetTextAddress(endPointRemote),                                CString(ec.message().c_str())) );             }else{                 m_funcMessage( CRString::Format(_T("%s : OnRecived [%s]"), CString(m_id.GetText().c_str()),                                CUdpSocket::GetTextAddress(endPointRemote) ) );

                // メンツリスト更新                 vector<char> vBuffer(*spBuffer);                 if( vBuffer.size() >= sizeof(CRUid) ){ // このソケットの送り主を自身のメンツリストにマージ                     CRUid id;                     std::copy( vBuffer.begin(), vBuffer.begin()+sizeof(id),                                stdext::checked_array_iterator<char*>(reinterpret_cast<char*>(&id),sizeof(id)) );                     vBuffer.erase( vBuffer.begin(), vBuffer.begin()+sizeof(id) );                     m_mapMember[id] = CEndpoint(endPointRemote);                 }else BOOST_ASSERT(false);                 // 送り主からのメンツリストを自身のメンツリストにマージ                 while( vBuffer.size() >= sizeof(CRUid)+sizeof(CEndpoint) ){                     CRUid id;                     std::copy( vBuffer.begin(), vBuffer.begin()+sizeof(id),                                stdext::checked_array_iterator<char*>(reinterpret_cast<char*>(&id),sizeof(id)) );                     vBuffer.erase( vBuffer.begin(), vBuffer.begin()+sizeof(id) );                     CEndpoint ep;                     std::copy( vBuffer.begin(), vBuffer.begin()+sizeof(ep),                                stdext::checked_array_iterator<char*>(reinterpret_cast<char*>(&ep),sizeof(ep)) );                     vBuffer.erase( vBuffer.begin(), vBuffer.begin()+sizeof(ep) );                     if( id != m_id ){                                       // 自分自身は除く                         m_mapMember[id] = ep;                     }                 }

            }

            udpSocket.Receive( boost::bind(&CMain::OnReceived,this,_1,_2,_3,_4) );    // 次の読み込み待ちを開始         }

public:     CMain(const FuncMessage &funcMessage)         :m_id(CRUid::RandomGenerator())         ,m_funcMessage(funcMessage)         ,m_udpSocket(m_ioService)         ,m_apTimer(new deadline_timer(m_ioService))         {             Create(HWND_MESSAGE,CRect(0,0,0,0),_T(""),NULL);             ::SetTimer( m_hWnd, 0, 1, NULL );              m_apTimer->expires_from_now( boost::posix_time::millisec(0) );          // nTime秒後に             m_apTimer->async_wait( boost::bind( &CMain::OnDeadlineTimer, this, _1 ) );         }

    ~CMain()         {             m_apTimer.reset();             m_udpSocket.Close();             if( m_hWnd ) DestroyWindow();         }

    void OnDeadlineTimer(const boost::system::error_code& error)         {             if( error || error==boost::asio::error::operation_aborted ) return; // チェック

            if( m_apTimer.get() ){                      // 終了していないなら次のタイマーを設定                 m_apTimer->expires_at( m_apTimer->expires_at() + boost::posix_time::millisec(5000) );                 m_apTimer->async_wait( boost::bind( &CMain::OnDeadlineTimer, this, _1 ) );             }

            // メンツリスト送信             boost::shared_ptr<vector<char>> spData(new vector<char>);             std::copy( reinterpret_cast<const char*>(&m_id), reinterpret_cast<const char*>(&m_id)+sizeof(m_id),                        std::back_inserter(*spData) );             for(std::map<CRUid,CEndpoint>::const_iterator i=m_mapMember.begin(); i!=m_mapMember.end(); i++ ){                 const CRUid &id = i->first;                 std::copy( reinterpret_cast<const char*>(&id), reinterpret_cast<const char*>(&id)+sizeof(id),                            std::back_inserter(*spData) );                 const CEndpoint &ep = i->second;                 std::copy( reinterpret_cast<const char*>(&ep), reinterpret_cast<const char*>(&ep)+sizeof(ep),                            std::back_inserter(*spData) );             }

            CString sSendTo;             for(std::map<CRUid,CEndpoint>::const_iterator i=m_mapMember.begin(); i!=m_mapMember.end(); i++ ){                 const CEndpoint &ep = i->second;                 ip::address addr(boost::asio::ip::address_v4(ep.m_nIpv4));                 ip::udp::endpoint endpoint( addr, ep.m_nPort );                 m_udpSocket.SendTo( endpoint, spData );                 sSendTo.Format(_T("%s [%s]"),CString(sSendTo),CUdpSocket::GetTextAddress(endpoint));             }             if( !sSendTo.IsEmpty() ){                 m_funcMessage( CRString::Format(_T("%s : SendTo %s"), CString(m_id.GetText().c_str()), sSendTo ));             }         }

    void Server(unsigned short nPort)         {             boost::system::error_code ec;             if( !m_udpSocket.Bind(nPort,ec) ){                 m_funcMessage( CRString::Format(_T("%s : Bind Error [%s]"), CString(m_id.GetText().c_str()),                                                 CString(ec.message().c_str()) ) );                 return;             }             m_udpSocket.Receive( boost::bind(&CMain::OnReceived,this,_1,_2,_3,_4) ); // 読み込み待ちを開始         }

    void Client(const std::string &sDomain,const std::string &sPort)         {             boost::shared_ptr<vector<char>> spData(new vector<char>);             std::copy( reinterpret_cast<const char*>(&m_id),                        reinterpret_cast<const char*>(&m_id)+sizeof(m_id), std::back_inserter(*spData) );              ip::udp::resolver resolver(m_ioService);             ip::udp::resolver::query query(ip::udp::v4(), sDomain, sPort );             boost::system::error_code ec;             ip::udp::resolver::iterator iterator = resolver.resolve(query,ec);             if( ec ){                 m_funcMessage( CRString::Format(_T("%s : resolve Error [%s]"),                                               CString(m_id.GetText().c_str()), CString(ec.message().c_str()) ) );                 return;             }             m_udpSocket.SendTo( *iterator,spData );             m_udpSocket.Receive( boost::bind(&CMain::OnReceived,this,_1,_2,_3,_4) );   // 読み込み待ちを開始         }

};

CUdpHolepunching::CUdpHolepunching(const FuncMessage &funcMessage) :m_main(*new CMain(funcMessage)) { }

CUdpHolepunching::~CUdpHolepunching() {     delete &m_main; }

void CUdpHolepunching::Server(unsigned short nPort) {     m_main.m_ioService.post( boost::bind( &CMain::Server, &m_main, nPort ) ); }

void CUdpHolepunching::Client(const std::string &sDomain,const std::string &sPort) {     m_main.m_ioService.post( boost::bind( &CMain::Client, &m_main, sDomain, sPort ) ); }

UDP ホールパンチングの仕組み上、穴をあけずとも UDP が通る環境が一つ必要です。
STUN サーバーと言われるもの。
サンプルアプリでは「サーバー起動」ってすると、UDP ポートを指定して待ち受け状態になります。
(とはいえ、標準化されてるプロトコルを実装してるわけではなく、オレオレ実装です。)

各端末(クライアントPC)は、このサーバーに接続することで、自身の NAT に穴を開けることと同時に、サーバーから各端末のエンドポイント情報を貰います。
あとは、各端末同士がそのエンドポイントに対して送信し合うことで P2P 通信を行う。という寸法です。

サンプルアプリでは、サーバーもクライアントも、すべての相手に対し、キープアライブも兼ねて、5秒毎に各端末のエンドポイント情報を送信し続けます。

というわけで、NAT 越えの P2P 通信自体は出来ることがわかったんですが、実用的にするのはいろいろハードルがあって、
Symmetric NAT 内の端末に対しては、サーバーなりが橋渡しをして通信しないといけない。とか、
UDP すら通さないような環境向けに TCP で橋渡しするようなサーバーを用意する。とか、
UDP を使うので、TCP 並の信頼性とか順序の安定性が必要なら自前実装しなきゃ。とか、
同じ NAT 内の端末同士は、ローカルIPで通信させるなり対策しなきゃ。(たぶん一般的なルーターでは、自分自身が開けたポートに自分自身から接続は出来なさそうなので)。とか。

この程度は世の P2P アプリ(skypeとか)は当然のように実現してるんだと思います。御見それです。

これらも楽しそうなので作ってみたいですが、仕事かなにかで必要になってくれないと手を出しずらいです。大変そうなので。

上記のソース一式はこちらからお願いします。例によって windows 用です。MFC 使ってます。
なにか間違いとかご意見とかればぜひお願いします。

ありがとうございました。


2014年9月8日(月曜日)

Magome に MML の機能を入れてみました

カテゴリー: - takatsuka @ 11時53分43秒
  • クラウドMIDIシーケンサ Magome に MML 打ち込みの機能を入れてみました。
    昨今のシーケンサというかDAWでは、ステップ入力自体があんまりなさそうに思うんですが、グラフィカルで直観的なUIと、テキストでカタカタと打っていく方式を組み合わせると、けっこう便利なんじゃなかろうかと思ってたところ、確かに、テキストで打ち込んだ音符がその場でピアノロールで表示されるっていうのは、気分いいです。
  • ステップ入力といえばレコンポーザが有名だったと思うんですが、実はちゃんと使ったことはないです。自分の場合、打ち込みは BASIC 言語から入って、その流れで MML 打ち込みが普通になって、それから MAC で Studio Vision を使い始めたので、王道のステップ入力というのをよく知りません。
  • ということもあり MML です。MML が ステップ入力 というカテゴリに入るのかわかりませんが、キーボード(鍵盤ではなくPCのキーボード)で打ち込むというのは慣れれば結構ラクだと思うんです。それに、書式の工夫次第で可能性が広がりそうだし。
  • 関数をこさえて呼べばフレーズが勝手に鳴るとか、スケール名を入れると音符が勝手にそのスケールにアジャストされる。とか、サビのキーが高すぎときには、その手前で3度くらいスムーズに下げるような和声学に基づいたモーションを生成してくれる。とか。
  • と、アイデアだけは広がるんですが、実現させて使ってみないとどういうものかわからない。頭の中だけで完成形をイメージできない。ってのが、自分の想像力不足かなと思います。
  • 形にするのが一番大変なとこでもあり、楽しいとこでもあるんで、徐々に進めてこうと思います。ご助言ご意見などあればぜひお願いいたします。

2014年7月24日(木曜日)

magome のサイトを xoops cube で刷新

カテゴリー: - takatsuka @ 00時21分51秒

magome のサイトを xoops cube を使ったものに刷新しました。

ユーザー登録&管理の仕組みを自前で組むのは手間かかりそうだし、便利なプラグイン(モジュール)がそのまま使えるのはラクだなという理由です。 ラクな分カユいとこに手が届きづらくなるデメリットはきっとあると思うんですが、それを帳消しに出来るほどのメリットがあると思いました。開発者の方々には感謝です。

で、今後もモジュール開発をするであろう主に未来の自分用にメモを残しておこうと思いました。間違いとかあればぜひご指摘頂ければ幸いです。

ノウハウメモ

DB

  • テーブル作成は、"モジュール/sql/mysql.sql” を用意して SQL を書く。それを、xoops_version.php の$modversion[’sqlfile’][’mysql’] = “sql/mysql.sql”; って指定。
    • なので、それを反映させるには、モジュールの再インストールが必要。
    • なお、$modversion[’tables’][index] = “テーブル名” への反映もしないと、モジュールアンインストール時にテーブルを削除してくれない。
    • ここで書くテーブル名は、そのまま採用されるわけではなく、プリフィックスが付加される。なのでDB操作時のSQL文でも、プリフィックスの考慮を忘るべからず。
  • DB操作は、$xoopsDB っていう変数のメンバを使うべし。
  • $xoopsDB->queryF( $query ) は、UPDATE系でコールすべし。それ以外は $xoopsDB->query( $query ) を使うべきっぽい。

preload

  • XOOPS_ROOT 直下の preloadフォルダ と、モジュールの下の preloadフォルダ では動作が違う。全ページに影響させたい場合は XOOPS_ROOT 直下の preloadフォルダ に置くべきっぽい。(が、このあたりは全然把握不足)

REST

  • XMLとかJSONを返すようなwebサービスのページを作りたい場合、そのページの最後の「include XOOPS_ROOT_PATH."/footer.php”;」をコールせずに、自前でechoすれば良いっぽい。(が、お作法的に正しいのかわからない)

表示

条件によって左右のサイドバーとかを非表示にしたい。

  • 各領域の表示をON,OFF出来るような条件文を書いたテーマを自前で用意して対応する。(が、もっとスマートな方法があるのかもしれない。)

テンプレート

  • smartyの書式は「<{○○}>」で括るべし。

トラブったメモ

  • 日本語が表示されない。日本語のlanguageファイルが無視される。
    • UTF8 が標準文字コードっぽいので、languageファイル は 「japanese」ではなく「ja_utf8」になる。(本来は「english」も含めた3種を用意すべき?)
  • テンプレートファイルを編集してもページが変わらない。
    • テンプレートを書き換えたらモジュールのアップデートが必要。もっと手軽な方法があるなら知りたい。
  • モジュールのアンインストールしたとき、作ったテーブルを削除してくれない。
    • xoops_version.php の $modversion[’tables’][index] = “テーブル名” の記述が漏れてるか確認。

2014年7月6日(日曜日)

XOOPS Cube の進化っぷりにビックリ

カテゴリー: - takatsuka @ 09時30分36秒

新規で会員制サイトをこさえようと思っておったところ、昨今はフリーの CMS (とかその手のもの)が沢山あるので迷っておりました。

WordPress や OpenPNE とかは活発そうだし、Movable Type は有料版もあるだけに品質は良さそうだし。
どれであっても便利っぽいし、カスタマイズすれば本来の用途以外にも使えそうで、何を選択しても間違いではなさそう。

がしかし今回は、自社サイトでも使わせてもらってる XOOPS でやってみようかなと思いました。
諸々の事柄に対して一番ツブシが利きそう。(って抽象的な想像な上に、根拠もそういう印象持っただけって理由なんですが。)

なにはともあれ、自社サイトはもう10年近く前にこさえたものってこともあり、今の XOOPS Cube の進化っぷりに物凄く驚いた次第。

インストールが簡単なのはそのまま、プラグインとかテーマは一覧から選んでインストールできるようになってる、アップデートも通知してくれちゃって。昨今の CMS に全然見劣りしてない。
日本語との相性やプラグイン開発用の情報は問題なさそうだし。

色々な CMS を比較できるほど触ったわけではなく詳しくもないんですが、会員制サイトを、吊るしではない前提でこさえるなら、XOOPS CUBE 良さそうだなって思いました。開発者の方に感謝です。


2014年4月19日(土曜日)

VPS 上で仮想化を活かそうか

カテゴリー: - takatsuka @ 00時41分41秒

以前から試したいと思ってたことを隙間を見てやってみました。

流行りのVPSサービスを使って、その上で、さらに仮想化して複数のOSを動かすこと。Nested Virtualization って言葉もあるみたい。

具体的には さくらのVPS を利用して、まず winodws2003server std x86 を動かして、その上に VirtualBox で BlueOnyx5107R(CentOS6.5 x86) を動かしてみました。

・w2k3 は Virtio を有効にしてインストールしたかったのですが、w2k3 のインストーラは追加ドライバを FDD からしか読めないようで断念しました。Virtio 無効なら素の ISO イメージですんなりインストールできました。

・w2k3 の上に、VirtualBox ではなく VMware server 1.0 を入れてもみましたが、そのケースでは BlueOnyx5107R が起動できず断念しました。(なお 5106R は行けました。)

・暇があれば w2k3 ではなく linux 入れて KVM が動かくか試したいです。さくらのVPS 自体が KVM なので、KVM on KVM ってことになるんですかね。

・なお実運用となるとライセンス云々やVPS上の禁止事項を要確認かもですが、ここでは触れません。

・気になるパフォーマンスについてですが BlueOnyx のコンパネ操作は普通に使えました。・・だけじゃ参考にならないかもですがちょっとよくわかりません。というのも、さくらのVPS は本契約するまでは帯域制限がかかっているようで、回線周りが絡むものについては判断できません。しかし、PentiumM クラスの1台で数十のサイトを同居させてるくらいの物は現役で沢山稼働してますし、動画配信とかしなければ Nested Virtualization でも十分使える気がします。

・VirtualBox 上に windows2000 も入れてみたので、暇があれば何か派手なベンチソフトを動かして確認してみたいです。が、ベンチソフトって結果の数値をみてもどう判断していいかわからないので、ホントに暇だったらやるかもくらいで。。。

・・・という感じです。

ちなみに、調査するちょっと前に知ったんですが、VPSサービスって、ユーザーにはHDDイメージを提供してはくれないらしく、それが意外でした。つまり、仮想化のメリットである、環境丸ごとをHDDイメージファイルで扱えるってことが出来ないみたいです。(技術と時間があればなんとかなりそうですが、サービスとしてはどこの業者も扱ってないみたいです。たぶん。この認識に誤りあればぜひご指摘頂きたいです。)
さらに、VPSなんだからスペックアップのサービスくらいは提供されてるんだろうと思ってたら、たぶんこれも今現在どこも提供してくれてないみたいです。(多分です。これももし違ったらご指摘頂きたいです。)

このヘンはきっと色々と事情があるんでしょう。想像するに技術的な問題だけじゃなさそうだなって気がします。

というわけで、VPS 上でさらに仮想化をすることのメリットとしては、仮想化のホストを管理下に置けるので、HDD イメージのファイルコピーのみでサーバーを引っ越すとか、手元のローカル環境で起動してデバッグするとか、が可能になるというあたりでしょうか。

特にサーバーの引っ越し作業(=ほぼ同等の環境の最再構築作業)はホントに億劫です。手間もコストも忍耐力(ハナから仮想化しとけばこんなメンドウなことブツブツ・・って思わないようにする忍耐)も必要です。これを避けることが出来るだけでも十分メリットです。

というか、そんなことを考えるくらいなら、コストアップを覚悟して IaaS とかのクラウドサービス(って言うのでしょうか)を使えばいいってことなるのかもですが、そっちはまだ勉強不足です。頑張ります。

というわけで、単なる技術的な興味だけの調査ですが、いちおうIT業界の隅っこでカサカサと生息してる身分ですから、この手の雑多な知識や貧乏テクがお客様の無駄な出費を減らすことに繋がるだろう。って自分に言って自分をなだめてます。

金曜の夜のちびちび嗜みながらの作文はなかなかに筆(キータッチ)が進むということがわかりました。びばふらいどぇぇ。


2013年9月1日(日曜日)

MIDIシーケンサソフト「Magome」

カテゴリー: - takatsuka @ 22時45分37秒

ひっそりと粛々とサンデープログラミングで進めてた MIDIシーケンサソフトを公開してみようと思います。
まだまだ実験アプリの域を出ていませんが、公開することで開発に多少でも弾みがつくと嬉しいなと思っています。
音楽制作が好きな方や興味をお持ちの方のご意見頂けば幸いに思います。
https://tr9.sakura.ne.jp/magome/

  • 開発コードネームは「Magome」です。
  • クラウドベースの MIDIシーケンサソフトです。一通りの楽曲制作作業が出来ることを念頭に、フルスペックの DAW を目指しています。
  • 音楽制作をしている方及び興味を持っている方を対象に、スタンドアロンとしても使いやすい音楽制作環境ということと、ネットならではの面白い使い方の二つを提案していきたいと思っています。

よろしくお願い申し上げます。


2013年8月18日(日曜日)

ホームページの引っ越し

カテゴリー: - takatsuka @ 21時36分59秒
  • ホームページの引っ越し。 ホームページの引っ越しというかPHP&MySQLのバージョンアップをしてみました。 XOOPSを使わせて頂いておりますが、ちょっと一筋縄では行かないとこがあったので、そのへんの備忘録を兼ねて。
    1. DBのバックアップを取る。phpMyAdmin を使った。
    2. PHPを 5.2 → 5.4 に変更
    3. MySQL を 4.x → 5.5 に変更
    4. phpMyAdminで、DBを復元
      1. 新DB は全て ujis を選択して使う。
      2. 復元するときに logcounterx まわりでエラー。 → 原因はわからんが、アクセスのログなので重要ではなさげと思って復元をあきらめた。
      3. 復元するときに CREATE TABLE でエラー。TIMESTAMP(14) を TIMESTAMP に変更。
    5. XOOPSの設定ファイル(mainfile.php )を変更。DBのホスト名やDB名、パスワード等。
    6. 文字化け対策に、/class/database/mysqldatabase.php 236行目付近の$result =& mysql_query($sql, $this->conn); の上に mysql_query("SET CHARACTER SET ujis”, $this->conn); を追加
    7. PHP5.4で、htmlspecialchars のデフォルト引数が変更されたようなので、コード上の全ての htmlspecialchars の引数を明示的に指定するように変更。
      • 旧PHPと同じ動作をするデフォルト引数付きの関数を用意して関数をそっちに全置換(という手抜き対応)。
      • 注意点として、$var->htmlspecialchars みたいな箇所があるが、よくわからんので、ここは変更しない。
    8. tinyd のコンテンツの対応
      1. コンテンツファイルが EUC-JP になってないものが表示されなくなったので、EUC-JPで保存し直し。
      2. コンテンツファイルによっては文字が化けるみたいなので、頭のほうに <!– <p>ページ文字化けしないように</p> –> みたいな文を挿入。原因はよくわからんがこれで文字化けは消えた。
      3. ページラップ mod_rewrite が動作しなくなった。原因はよくわからんので、WRAP2 に変更してお茶を濁す。

2013年7月21日(日曜日)

リファラースパム

カテゴリー: - takatsuka @ 21時27分12秒

ログみると、リファラースパムで .ru ドメインがやたら多いので、そのあたりで流行ってんのかなと思ってたら、 .ws なんていうドメインも出てきた。よくわからんですがワークステーション的なそそるドメインだなと思いました。


2013年3月12日(火曜日)

Yahoo!ボックス1TB月額¥300

カテゴリー: - takatsuka @ 22時50分16秒
Yahoo!ボックス を定期バックアップ先として使っているんですが、近日提供予定となっていた「1TB月額¥300」というサービスは、やっぱり提供しないという案内が出ておりました。


しかも、今後提供するサービスは「100GB月額¥700」というまったく魅力のないものとなっており、残念に思っている人は自分も含め多い気がします。


Yahoo!以外にもオンラインストレージは色々あるので、別の良いサービスを探すなり併用するなりしたいところです。




・・フト、自分の貧乏にわか知識でも似たようなサービスを提供できちゃうんじゃないだろうか?と思いざっくり計算してみました。


初期コストとして、
HDDは3TBのものが¥10479。RAIDとかはナシ。
サーバーはHPかNECあたりの激安サーバー1台¥10,000程度。
1台のサーバーにHDDは何台繋げられるのか?よくわからんのですが、少なくとも4台はいけるだろうってことで、PC1台あたりHDD12TBで¥41,437。1TBあたり¥3,453。
アプリは頑張って自作。


で、ランニングコストとして、
サーバーは自社内に設置。
回線は、帯域遅くてもいいということにして今ある回線を使うことに。


電気代よくわからんのですが、とりあえずPC1台あたり月¥3,000として1TBあたり¥250・・・あれ?けっこう高いな。


1TB月額¥300で提供すると¥50しかプラスにならないです。
これじゃ初期コストをペーするのが数年先になってしまう。


電気代の見積もりが高いのか、サーバー1台あたりのHDDが少な過ぎなのか、USB-HDDとかNASとか上手く使えばもう少しなんとかなるのかな。


まぁ何にせよ1TB月額¥300だと厳しそうだなと素人ながらに思いました。

2013年3月4日(月曜日)

プリンタ新調しました

カテゴリー: - takatsuka @ 12時59分01秒

NEC PR-L5600C カラーレーザープリンタです。
使っているモノクロレーザー複合機のトナー切れに際し、トナー購入を検討してみたら、

大して変わらない値段で新品のカラーレーザープリンターが買えるってことに気が付いて購入。¥6,980也。

とはいえ自分としては、仕事上もプライベートでも、紙に印刷を必要とすることは皆無なので、プリンタそのものの必要性をあまり感じることが出来ず・・・。

/*
自分、プログラム書く仕事してますが、仕様書とかコードとか印刷することがないです。電子ファイルのほうが、検索できるしゴミも増えないしコピペ出来るし便利な気がします。
その代わりに画面(モニタ)は大きいほうがいいなと思います。

写真印刷については、使いたい時は必ずインク切れ&インク買って装着したら実はノズルが詰まってて要修理・・・みたいな心配のない お店プリント を使ったほうがいいなかと思います。
*/

最近はe-taxとか、ネットで投票とかも聞きますから、ネット化、ペーパーレス化の流れを感じます。
年賀状とか名刺とか、文化、風習的なものはスグには変わらないので、個人向けプリンタ自体がなくなることはないと思うんですが、
紙ベースのプリンタは今の時代が底値なんだろうなと思ってしまいました。

で、数年後には、プリンタと言えば3Dプリンタでしょ!という感じでしょうか。


2013年1月11日(金曜日)

HP ML115 G5 電源ユニット交換

カテゴリー: - takatsuka @ 08時21分46秒
社内サーバーとして使っていた HP ML115 G5 が故障しました。
いつの間にか電源が落ちていて、電源スイッチを押してもうんともすんとも言わない状態。 
たぶん電源ユニットが壊れたんだろうなと、根拠なく察しをつけて、社内の部品取りPCから移植を考えました。
メーカー製PCとはいえ、きっと汎用品が使われているだろうと、これまた根拠なく察しをつけて。
 
マザーボード側と接続するコネクタは合うし、容量的にも純正品より大きいのがあったので、取り付けてみたところ、無事に電源が入り普通に起動。
 
電源が壊れたという読みは正解だったようで、5年近く24時間稼動だったんで、寿命だったんだろうと思います。
 
とにかくよかった。
と、一息つきたいところですが少々問題が。
HP ML115 G5 で使われている電源ユニットは、規格品とは寸法が違う模様で、ケース側のネジ穴と合わず、ネジ止めできない。
ネットで調べると、そういうものらしく、みんな苦労されている模様。
 
情報を公開してくれている皆さまに感謝しつつ、
ケースを横置きにして電源は固定してない状態のまま稼動再開して、
今日のところは作業終了。

後日、ドリル持ってきてケースにネジ穴を開ける作業をしようと思いました。

穴あけ作業では鉄粉が機器に飛ばないようにしないと・・・とか、ちょっと面倒。

2013年1月7日(月曜日)

新年あけましておめでとうございます

カテゴリー: - takatsuka @ 11時12分36秒


今年は宣伝もかねて記事投稿を増やして行こうと思っております。
よろしくお願いいたします。

さて、弊社はサーバー運営なども行っております。あまりアピールしてこなかったんですが。

必要十分なスペックで、持っている貧乏テク知識を駆使した、とにかくコストパフォーマンスの良いサーバー運営を目指してます。

直接運営しているものの例として、
数十のサイトが入ってるレンタルサーバーと、ケータイサイト複数、開発実験用サイト数個、社内のナレッジ管理及び個人のシンクライアント用サーバーなどを、
データーセンター内のサーバーと、オフィス内に設置してあるサーバー(普通のPC)の2台で運営しています。

これらは、システムの構築初期費用は別として、電気代や回線代、バックアップ用システムなども含めて、月額実費約2〜3万円程度で運用しています。

もちろん金に糸目をつけなければ何でもアリですが、それだと勿体無いです。

サーバー云々に限らず、IT 化という面では、社員が数人の会社でもメリットはあります。
しかし、特に中小規模の会社の IT 化は無駄にコストをかけがちな気がします。

オーバースペックにはならず、必要十分なスペックの IT 化のお手伝いをさせて頂きます。ぜひご相談下さい。


2012年12月12日(水曜日)

サーバーのバックアップをオンラインストレージサービスで

カテゴリー: - takatsuka @ 08時38分16秒

定期バックアップを考えてみました。

大事なサーバーはRAIDになってますが、それでもやっぱりバックアップは重要ってことで、サーバーの全内容を自動で定期的にバックアップ&念のため遠隔地保存をしています。

がしかし、遠隔地保存と偉そうに謳っても、実は職場と自宅の2か所なので、いまいちカッコがつかないなと思っていたんですが、
最近はオンラインストレージというのがあり、それがまた大容量低価格になってきている。

これは是非使ってみちゃどうだろうかと思い、やってみたところ・・・簡単に実現出来ました。

とりあえずは Yahoo! のアカウントがあったので、Yahoo!Box っていうサービスで試しました。
アップロードにえらい時間がかかる印象を受けましたが、用途がバックアップなので、裏で勝手に転送しててくれれば転送速度は気にはなりません。

ただ、バックアップは全自動で!という運用は外せないので、手動操作が必要なサービスだと無理だったのかもしれません。

気を付ける点として、大事なバックアップ(データ)を他社のサーバーに置くことになるので、万が一のデータ流出などを考慮して暗号化したりという工夫は必要ですが、とても良い手段だと思いました。
サーバーを、外部ではなく手元に置きたいケースでは特に有用かなと思います。


2011年7月20日(水曜日)

Kate

カテゴリー: - ohashi @ 15時15分49秒

 暑い日が続いておりますが、皆様いかがお過ごしでしょうか。こちらのブログは1年以上のご無沙汰となってしまいました。すみません…

 さて、弊社では、この6月末に創刊された、千葉県木更津・君津・富津・袖ヶ浦地域のクーポン付きフリーペーパー、Kate(ケイト)のWeb版のシステム面でお手伝いさせて頂きました。

 木更津・君津・富津・袖ヶ浦(いわゆる上総エリアですね)におでかけの際には、ぜひともご利用頂きたいと思う次第です。
Kate



Kateへはこちらからどうぞ!
http://www.kate-omot.jp


2009年10月4日(日曜日)

64Bit Windows7 って

カテゴリー: - takatsuka @ 02時11分14秒

Windows7 が発売ってことで盛り上がってるようですが、この版から、64Bit 版も同根されるってことで、64Bit が浸透しつつあるのかなと思いつつ、どうにも解せないことが・・。

PC バンドルで Windows7 64Bit 版がプリインストールされるのって、いかがなものかと感じてしまいます。

32Bit と比べて 64Bit の恩恵が得れるのって沢山のメモリを扱えることだと思うんす。
とはいえ 32Bit でも実質 3.5G くらいまで扱えるので、それ以上のメモリを積んでないと 64Bit Windows7 の恩恵はないハズ。

恩恵ないどころか、
64Bit ネイティブアプリ(OS自体もしかり)は、32Bit アプリに比べてメモリ消費も多くなる分、
メモリ 4G 程度の PC なら、32Bit Windows7 を使ってたほうが利口だろうと思うんす。

それに、アプリも、64Bit ネイティブアプリしか提供しませんてな時代は、まだまだ先だと思います。

しかしメーカー製 PC の中には、64Bit Windows7 をプリインストールしときながら、搭載メモリは 2G とか、増設しても最大 4G までとか。
なんつーか、購入者にメリットないんじゃね?宣伝文句にしたいってことか?って思ってしまいます。

とはいえ、64Bit Windows に移行してくれるのは良いことだなとは思ってるっす。64Bit 普及の為にあえてやっていると思えば、メーカー様に感謝っす。

以上、自分もし何か勘違いとかしてたらご指摘頂き度。

64Bit ネイティブアプリは32Bitアプリに比べてかなり速く動くとか、そういうメリットがあるんすかね。
試してないけど想像するに、たいして速くはならなそうな気がします。モノによっては遅くなるのもありそうだし・・。


2009年4月15日(水曜日)

WM版Skypeはケータイの代わりになるか?

カテゴリー: - ohashi @ 10時51分18秒

 先日、iPhone・iPod TouchでSkypeが正式リリースされたというニュースを目にして、思い出したようにWILLCOM 03で固定・携帯電話への通話を試してみました。かなり今更ですが。

 で、以下感想など…

 月695円の基本使用料のみで通話し放題か、固定電話に2.66円/分、携帯電話に17.5円/分を1,500円単位でプリペイド購入のプランがある。
自分の場合、現在月当たりの通話料金が695円(友達少ないので…)にすら満たないので、使うならプリペイドかなぁ。
 ちなみにプリペイドは半年未使用だと有効期限が切れてしまうらしい。(一瞬でも通話すればOK)

 実家の無線LANにWILLCOM 03を繋いで会話した感じだと、感覚はケータイにかなり近い。この場合、パケット料金も掛からない。

 外に持ち出す場合、現在のウィルコムの回線速度では音声通話はムリ。パケット代は月MAX2,900円でそれ以降は定額なので、天井なしの通話料(固定
電話に10.5円/30秒、携帯電話に13.125円/30秒)と比較すると、それなりに電話を使うならば、かなりおトクなのだが残念…
 多分、イーモバの回線速度なら音声通話可能じゃなかろうか… WMの端末もあるし。

 とりあえず、無線LAN環境がある場所で電話する時は、Skypeを使ってみようかなぁ。
 でも相手には番号非通知になってしまうので、怪しがって出ない人がいるかも…

 というわけで、日頃お付き合いさせていただいている皆様、今後、番号非通知の電話がかかってきたらそれは僕かもしれません。


2008年9月28日(日曜日)

HP ML115G5

カテゴリー: - takatsuka @ 13時48分10秒

少し前に社内サーバーを HP ML110G2 から ML115G5 に入れ替えました。
ML115G5 は今話題(?)の激安サーバーの一つです。
社内向けサーバーなので、バックアップだけしっかりやっとけば、これで十分。
流石に素の状態だとキツイので、メモリ(もちろんNonECC)とHDD(旧サーバーから移植)は追加しましたが、本体¥15,000弱で買えてしまうのでコストパフォーマンスは最高です。

サーバー上のシステムの類は全て VMware Server 上の仮想PCの状態で組んであるので、旧サーバーからの引越しも単なるファイルコピーで済みます。VMware を採用するメリットを痛感した次第。VMware に感謝です。

サーバー本体のスペックもあがったので、現在 ML115G5 上に VMware のゲストOS が5つ動いてます。
流石にシングルコアだとツライかなと思う瞬間もありますが、とりあえず十分。
クアッドコアCPUも載せれるらしいので、ホントに足りないと思ったら考えようと。

ML115G5 とかの激安サーバーはホントにコストパフォーマンスが良くて、グラフィックカードとサウンドカードを付ければホビー用途でも十分いけそうです。
しかも自分の場合、USB接続の SonicCell なので音用PCとしてそのまま使えそうです。

とはいえ、例えば企業さんがクライアントPC として複数台購入するようなケースでは、Windows プリインストールされた激安ノートPC とかを選んどいたほうが結果的によさそうなので、臨機応変にって感じです。

今話題の激安サーバーPC は他に、NEC 110Ge、DELL T105 などでしょうか。
特に今 NTT-X さんで 110Ge は2台で2万円弱!1台あたり1諭吉で買えてしまうバラマキ状態です。興味ある方は是非。


67 queries. 0.102 sec.
Powered by WordPress Module based on WordPress ME & WordPress

カレンダー
2024年 4月
« 11月    
 123456
78910111213
14151617181920
21222324252627
282930  
月別過去ログ
カテゴリ一覧
検索
最近の投稿
最近のコメント
投稿者ブロック