`
javahigh1
  • 浏览: 1226818 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

Asterisk::AMI perl 实现

 
阅读更多

use Asterisk::AMI;
my $astman = Asterisk::AMI->new(PeerAddr => '127.0.0.1',
PeerPort => '5038',
Username => 'admin',
Secret => 'supersecret'
);

die "Unable to connect to asterisk" unless ($astman);

my $action = $astman->({ Action => 'Command',
Command => 'sip show peers'
});

DESCRIPTION ^

This module provides an interface to the Asterisk Manager Interface. It's goal is to provide a flexible, powerful, and reliable way to interact with Asterisk upon which other applications may be built. It utilizes AnyEvent and therefore can integrate very easily into event-based applications, but it still provides blocking functions for us with standard scripting.

SSL SUPPORT INFORMAION

For SSL support you will also need the module that AnyEvent::Handle uses for SSL support, which is not a required dependency. Currently that module is 'Net::SSLeay' (AnyEvent:Handle version 5.251) but it may change in the future.

CentOS/Redhat

If the version of Net:SSLeay included in CentOS/Redhat does not work try installing an updated version from CPAN.

Constructor

new([ARGS])

Creates a new AMI object which takes the arguments as key-value pairs.

        Key-Value Pairs accepted:
        PeerAddr        Remote host address     <hostname>
        PeerPort        Remote host port        <service>
        Events          Enable/Disable Events           'on'|'off'
        Username        Username to access the AMI
        Secret          Secret used to connect to AMI
        AuthType        Authentication type to use for login    'plaintext'|'MD5'
        UseSSL          Enables/Disables SSL for the connection 0|1
        BufferSize      Maximum size of buffer, in number of actions
        Timeout         Default timeout of all actions in seconds
        Handlers        Hash reference of Handlers for events   { 'EVENT' => /&somesub };
        Keepalive       Interval (in seconds) to periodically send 'Ping' actions to asterisk
        TCP_Keepalive   Enables/Disables SO_KEEPALIVE option on the socket      0|1
        Blocking        Enable/Disable blocking connects        0|1
        on_connect      A subroutine to run after we connect
        on_connect_err  A subroutine to call if we have an error while connecting
        on_error        A subroutine to call when an error occurs on the socket
        on_disconnect   A subroutine to call when the remote end disconnects
        on_timeout      A subroutine to call if our Keepalive times out
        OriginateHack   Changes settings to allow Async Originates to work 0|1

        'PeerAddr' defaults to 127.0.0.1.
        'PeerPort' defaults to 5038.
        'Events' default is 'off'. May be anything that the AMI will accept as a part of the 'Events' parameter for the 
        login action.
        'Username' has no default and must be supplied.
        'Secret' has no default and must be supplied.
        'AuthType' sets the authentication type to use for login. Default is 'plaintext'.  Use 'MD5' for MD5 challenge
        authentication.
        'UseSSL' defaults to 0 (no ssl). When SSL is enabled the default PeerPort changes to 5039.
        'BufferSize' has a default of 30000. It also acts as our max actionid before we reset the counter.
        'Timeout' has a default of 0, which means no timeout on blocking.
        'Handlers' accepts a hash reference setting a callback handler for the specified event. EVENT should match
        the contents of the {'Event'} key of the event object will be. The handler should be a subroutine reference that
        will be passed the a copy of the AMI object and the event object. The 'default' keyword can be used to set
        a default event handler. If handlers are installed we do not buffer events and instead immediately dispatch them.
        If no handler is specified for an event type and a 'default' was not set the event is discarded.
        'Keepalive' only works when running with an event loop. Used with on_timeout, this can be used to detect if
        asterisk has become un-responsive.
        'TCP_Keepalive' default is disabled. Activates the tcp keep-alive at the socket layer. This does not require 
        an event-loop and is lightweight. Useful for applications that use long-lived connections to Asterisk but 
        do not run an event loop.
        'Blocking' has a default of 1 (block on connecting). A value of 0 will cause us to queue our connection
        and login for when an event loop is started. If set to non blocking we will always return a valid object.

        'on_connect' is a subroutine to call when we have successfully connected and logged into the asterisk manager.
        it will be passed our AMI object.

        'on_connect_err', 'on_error', 'on_disconnect'
        These three specify subroutines to call when errors occur. 'on_connect_err' is specifically for errors that
        occur while connecting, as well as failed logins. If 'on_connect_err' or 'on_disconnect' it is not set, 
        but 'on_error' is, 'on_error' will be called. 'on_disconnect' is not reliable, as disconnects seem to get lumped
        under 'on_error' instead. When the subroutine specified for any of theses is called the first argument is a copy
        of our AMI object, and the second is a string containing a message/reason. All three of these are 'fatal', when
        they occur we destroy our buffers and our socket connections.

        'on_timeout' is called when a keep-alive has timed out, not when a normal action has. It is non-'fatal'.
        The subroutine will be called with a copy of our AMI object and a message.

        'OriginateHack' defaults to 0 (off). This essentially enables 'call' events and says 'discard all events
        unless the user has explicitly enabled events' (prevents a memory leak). It does its best not to mess up
        anything you have already set. Without this, if you use 'Async' with an 'Originate' the action will timeout
        or never callback. You don't need this if you are already doing work with events, simply add 'call' events
        to your eventmask. 
        If you are running an event loop and use blocking methods (e.g. get_response, check_response, action,
        simple_action, connected) the outcome is unspecified. It may work, it may lock everything up, the action may
        work but break something else. I have tested it and behavior seems unpredictable at best and is very
        circumstantial.

        If you are running an event-loop use non-blocking callbacks! It is why they are there!

        However if you do play with blocking methods inside of your loops let me know how it goes.

Actions

Construction

No matter which method you use to send an action (send_action(), simple_action(), or action()), they all accept actions in the same format, which is a hash reference. The only exceptions to this rules are when specifying a callback and a callback timeout, which only work with send_action.

To build and send an action you can do the following:

        %action = ( Action => 'Command',
                    Command => 'sip show peers'
                );

        $astman->send_action(/%action);

Alternatively you can also do the following to the same effect:

        $astman->send_action({  Action => 'Command',
                                Command => 'sip show peers'
                                });

Additionally the value of the hash may be an array reference. When an array reference is used, every value in the array is append as a different line to the action. For example:

        { Variable => [ 'var1=1', 'var2=2' ] }

        Will become:

        Variable: var1=1
        Variable: var2=2

        When the action is sent.

Sending and Retrieving

More detailed information on these individual methods is available below

The send_action() method can be used to send an action to the AMI. It will return a positive integer, which is the ActionID of the action, on success and will return undef in the event it is unable to send the action.

After sending an action you can then get its response in one of two methods.

The method check_response() accepts an actionid and will return 1 if the action was considered successful, 0 if it failed and undef if an error occurred or on timeout.

The method get_response() accepts an actionid and will return a Response object (really just a fancy hash) with the contents of the Action Response as well as any associated Events it generated. It will return undef if an error occurred or on timeout.

All responses and events are buffered, therefor you can issue several send_action()s and then retrieve/check their responses out of order without losing any information. In-fact, if you are issuing many actions in series you can get much better performance sending them all first and then retrieving them later, rather than waiting for responses immediately after issuing an action.

Alternatively you can also use simple_action() and action(). simple_action() combines send_action() and check_response(), and therefore returns 1 on success and 0 on failure, and undef on error or timeout. action() combines send_action() and get_response(), and therefore returns a Response object or undef.

Examples

        Send and retrieve and action:
        my $actionid = $astman->send_action({   Action => 'Command',
                                                Command => 'sip show peers'
                                });

        my $response = $astman->get_response($actionid)

        This is equivalent to the above:
        my $response =  $astman->action({       Action => 'Command',
                                                Command => 'sip show peers'
                                });

        The following:
        my $actionid1 = $astman->send_action({  Action => 'Command',
                                                Command => 'sip show peers'
                                });

        my $actionid2 = $astman->send_action({  Action => 'Command',
                                                Command => 'sip show peers'
                                });

        my $actionid3 = $astman->send_action({  Action => 'Command',
                                                Command => 'sip show peers'
                                });

        my $response3 = $astman->get_response($actionid3);
        my $response1 = $astman->get_response($actionid1);
        my $response2 = $astman->get_response($actionid2);

        Can be much faster than:
        my $response1 = $astman->action({       Action => 'Command',
                                                Command => 'sip show peers'
                                });
        my $response2 = $astman->action({       Action => 'Command',
                                                Command => 'sip show peers'
                                });
        my $response3 = $astman->action({       Action => 'Command',
                                                Command => 'sip show peers'
                                });

Originate Examples

        I see enough searches hit my site for this that I figure it should be included in the documentation.
        These don't include non-blocking examples, please read the section on 'Callbacks' below for information
        on using non-blocking callbacks and events.

        NOTE: Please read about the 'OriginateHack' option for the constructor above if you plan on using the 'Async'
        option in your Originate command, as it may be required to properly retrieve the response.

        In these examples we are dialing extension '12345' at a sip peer named 'peer' and when the call connects
        we drop the channel into 'some_context' at priority 1 for extension 100.

        Example 1 - A simple non-ASYNC Originate

        my $response = $astman->action({Action => 'Originate',
                                        Channel => 'SIP/peer/12345',
                                        Context => 'some_context',
                                        Exten => 100,
                                        Priority => 1});

        And the contents of respone will look similiar to the following:

        {
                'Message' => 'Originate successfully queued',
                'ActionID' => '3',
                'GOOD' => 1,
                'COMPLETED' => 1,
                'Response' => 'Success'
        };

        Example 2 - Originate with multiple variables
        This will set the channel variables 'var1' and 'var2' to 1 and 2, respectfully.
        The value for the 'Variable' key should be an array reference or an anonymous array in order
        to set multiple variables.

        my $response = $astman->action({Action => 'Originate',
                                        Channel => 'SIP/peer/12345',
                                        Context => 'some_context',
                                        Exten => 100,
                                        Priority => 1,
                                        Variable = [ 'var1=1', 'var2=2' ]});

        Example 3 - An Async Originate
        If youre Async Originate never returns please read about the 'OriginateHack' option for the constructor.

        my $response = $astman->action({Action => 'Originate',
                                        Channel => 'SIP/peer/12345',
                                        Context => 'some_context',
                                        Exten => 100,
                                        Priority => 1,
                                        Async => 1});

        And the contents of response will look similiar to the following:

        {
                'Message' => 'Originate successfully queued',
                'EVENTS' => [
                        {
                                'Exten' => '100',
                                'CallerID' => '<unknown>',
                                'Event' => 'OriginateResponse',
                                'Privilege' => 'call,all',
                                'Channel' => 'SIP/peer-009c5510',
                                'Context' => 'some_context',
                                'Response' => 'Success',
                                'Reason' => '4',
                                'CallerIDName' => '<unknown>',
                                'Uniqueid' => '1276543236.82',
                                'ActionID' => '3',
                                'CallerIDNum' => '<unknown>'
                        }
                        ],
                'ActionID' => '3',
                'GOOD' => 1,
                'COMPLETED' => 1,
                'Response' => 'Success'
        };

        More Info:
        Check out the voip-info.org page for more information on the Originate action.
        http://www.voip-info.org/wiki/view/Asterisk+Manager+API+Action+Originate

Callbacks

        You may also specify a method to callback when using send_action as well as a timeout.

        An example of this would be:
        $astman->send_action({  Action => 'Ping',
                                CALLBACK => /&somemethod,
                                TIMEOUT => 7 });

        Equivalent in the new alternative sytanx:
        $astman->send_action({ Action => 'Ping' }, /&somemethod, 7);

In this example once the action 'Ping' finishes we will call somemethod() and pass it the a copy of our AMI object and the Response Object for the action. If TIMEOUT is not specified it will use the default set. A value of 0 means no timeout. When the timeout is reached somemethod() will be called and passed a reference to the our $astman and the uncompleted Response Object, therefore somemethod() should check the state of the object. Checking the key {'GOOD'} is usually a good indication if the response is useable.

Callback Caveats

Callbacks only work if we are processing packets, therefore you must be running an event loop. Alternatively, we run mini-event loops for our blocking calls (e.g. action(), get_action()), so in theory if you set callbacks and then issue a blocking call those callbacks should also get triggered. However this is an unsupported scenario.

Timeouts are done using timers and they are set as soon as you send the object. Therefore if you send an action with a timeout and then monkey around for a long time before getting back to your event loop (to process input) you can time out before ever even attempting to receive the response.

        A very contrived example:
        $astman->send_action({  Action => 'Ping',
                                CALLBACK => /&somemethod,
                                TIMEOUT => 3 });

        sleep(4);

        #Start loop
        $astman->loop;
        #Oh no we never even tried to get the response yet it will still time out

ActionIDs

This module handles ActionIDs internally and if you supply one in an action it will simply be ignored and overwritten.

Responses and Events

        NOTE: Empty fields sent by Asterisk (e.g. 'Account: ' with no value in an event) are represented by the hash
        value of null string, not undef. This means you need to test for ''
        (e.g. if ($response->{'Account'} ne '')) ) for any values that might be possibly be empty.

Responses

        Responses are returned as response objects, which are hash references, structured as follows:

        $response->{'Response'}         Response to our packet (Success, Failed, Error, Pong, etc).
                   {'ActionID'}         ActionID of this Response.
                   {'Message'}          Message line of the response.
                   {'EVENTS'}           Array reference containing Event Objects associated with this actionid.
                   {'PARSED'}           Hash reference of lines we could parse into key->value pairs.
                   {'CMD'}              Contains command output from 'Action: Command's. It is an array reference.
                   {'COMPLETED'}        1 if completed, 0 if not (timeout)
                   {'GOOD'}             1 if good, 0 if bad. Good means no errors and COMPLETED.

Events

        Events are turned into event objects, these are similar to response objects, but their keys vary much more
        depending on the specific event.

        Some common contents are:

        $event->{'Event'}               The type of Event
                {'ActionID'}            Only available if this event was caused by an action

Event Handlers

        Here is a very simple example of how to use event handlers. Please note that the key for the event handler
        is matched against the event type that asterisk sends. For example if asterisk sends 'Event: Hangup' you use a
        key of 'Hangup' to match it. This works for any event type that asterisk sends.

        my $astman = Asterisk::AMI->new(PeerAddr        =>      '127.0.0.1',
                                        PeerPort        =>      '5038',
                                        Username        =>      'admin',
                                        Secret          =>      'supersecret',
                                        Events          =>      'on',
                                        Handlers        => { default => /&do_event,
                                                             Hangup => /&do_hangup };
                                );

        die "Unable to connect to asterisk" unless ($astman);

        sub do_event {
                my ($asterisk, $event) = @_;

                print 'Yeah! Event Type: ' . $event->{'Event'} . "/r/n";
        }

        sub do_hangup {
                my ($asterisk, $event) = @_;
                print 'Channel ' . $event->{'Channel'} . ' Hungup because ' . $event->{'Cause-txt'} . "/r/n";
        }

        #Start some event loop
        someloop;

How to use in an event-based application

        Getting this module to work with your event based application is really easy so long as you are running an
        event-loop that is supported by AnyEvent. Below is a simple example of how to use this module with your
        preferred event loop. We will use EV as our event loop in this example. I use subroutine references in this
        example, but you could use anonymous subroutines if you want to.

        #Use your preferred loop before our module so that AnyEvent will auto-detect it
        use EV;
        use Asterisk::AMI:

        #Create your connection
        my $astman = Asterisk::AMI->new(PeerAddr        =>      '127.0.0.1',
                                        PeerPort        =>      '5038',
                                        Username        =>      'admin',
                                        Secret          =>      'supersecret',
                                        Events          =>      'on',
                                        Handlers        =>      { default => /&eventhandler }
                                );
        #Alternatively you can set Blocking => 0, and set an on_error sub to catch connection errors
        die "Unable to connect to asterisk" unless ($astman);

        #Define the subroutines for events
        sub eventhandler { my ($ami, $event) = @_; print 'Got Event: ',$event->{'Event'},"/r/n"; }

        #Define a subroutine for your action callback
        sub actioncb { my ($ami, $response) = @_; print 'Got Action Reponse: ',$response->{'Response'},"/r/n"; }

        #Send an action
        my $action = $astman->({ Action => 'Ping',
                                 CALLBACK => /&actioncb });

        #Do all of you other eventy stuff here, or before all this stuff, whichever
        #..............

        #Start our loop
        EV::loop



        That's it, the EV loop will allow us to process input from asterisk. Once the action completes it will 
        call the callback, and any events will be dispatched to eventhandler(). As you can see it is fairly
        straight-forward. Most of the work will be in creating subroutines to be called for various events and 
        actions that you plan to use.

Methods

send_action ( ACTION, [ [ CALLBACK ], [ TIMEOUT ] ] )

        Sends the action to asterisk, where ACTION is a hash reference. If no errors occurred while sending it returns
        the ActionID for the action, which is a positive integer above 0. If it encounters an error it will return undef.
        You may specify a callback function and timeout either in the ACTION hash or in the method call. CALLBACK is
        optional and should be a subroutine reference or any anonymous subroutine. TIMEOUT is optional and only has an
        affect if a CALLBACK is specified. CALLBACKs and TIMEOUTs specified during a method call override any found in
        the ACTION hash.

check_response( [ ACTIONID ], [ TIMEOUT ] )

        Returns 1 if the action was considered successful, 0 if it failed, or undef on timeout or error. If no ACTIONID
        is specified the ACTIONID of the last action sent will be used. If no TIMEOUT is given it blocks, reading in
        packets until the action completes. This will remove a response from the buffer.

get_response ( [ ACTIONID ], [ TIMEOUT ] )

        Returns the response object for the action. Returns undef on error or timeout.
        If no ACTIONID is specified the ACTIONID of the last action sent will be used. If no TIMEOUT is given it 
        blocks, reading in packets until the action completes. This will remove the response from the buffer.

action ( ACTION [, TIMEOUT ] )

        Sends the action and returns the response object for the action. Returns undef on error or timeout.
        If no ACTIONID is specified the ACTIONID of the last action sent will be used.
        If no TIMEOUT is given it blocks, reading in packets until the action completes. This will remove the
        response from the buffer.

simple_action ( ACTION [, TIMEOUT ] )

        Sends the action and returns 1 if the action was considered successful, 0 if it failed, or undef on error
        and timeout. If no ACTIONID is specified the ACTIONID of the last action sent will be used. If no TIMEOUT is
        given it blocks, reading in packets until the action completes. This will remove the response from the buffer.

disconnect ()

        Logoff and disconnects from the AMI. Returns 1 on success and 0 if any errors were encountered.

get_event ( [ TIMEOUT ] )

        This returns the first event object in the buffer, or if no events are in the buffer it reads in packets
        waiting for an event. It will return undef if an error occurs.
        If no TIMEOUT is given it blocks, reading in packets until an event arrives.

amiver ()

        Returns the version of the Asterisk Manager Interface we are connected to. Undef until the connection is made
        (important if you have Blocking => 0).

connected ( [ TIMEOUT ] )

        This checks the connection to the AMI to ensure it is still functional. It checks at the socket layer and
        also sends a 'PING' to the AMI to ensure it is still responding. If no TIMEOUT is given this will block
        waiting for a response.

        Returns 1 if the connection is good, 0 if it is not.

error ()

        Returns 1 if there are currently errors on the socket, 0 if everything is ok.

destroy ( [ FATAL ] )

        Destroys the contents of all buffers and removes any current callbacks that are set. If FATAL is true
        it will also destroy our IO handle and its associated watcher. Mostly used internally. Useful if you want to
        ensure that our IO handle watcher gets removed. 

loop ()

        Starts an eventloop via AnyEvent.

See Also ^

Asterisk::AMI::Common, Asterisk::AMI::Common::Dev

分享到:
评论

相关推荐

    node-v0.10.31-sunos-x86.tar.gz

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

    node-v0.10.44-linux-x86.tar.gz

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

    30KW三相PFC充电桩充电模块项目开发设计方案CCS源码AD原理图bom测试报告

    30KW三相PFC充电桩项目开发设计方案CCS源码AD原理图bom测试报告

    node-v0.10.32-x64.msi

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

    JAVA五子棋手机网络对战游戏的设计与实现(源代码+LW).zip

    JAVA五子棋手机网络对战游戏的设计与实现(源代码+LW)JAVA五子棋手机网络对战游戏的设计与实现(源代码+LW)JAVA五子棋手机网络对战游戏的设计与实现(源代码+LW)JAVA五子棋手机网络对战游戏的设计与实现(源代码+LW)JAVA五子棋手机网络对战游戏的设计与实现(源代码+LW)JAVA五子棋手机网络对战游戏的设计与实现(源代码+LW)JAVA五子棋手机网络对战游戏的设计与实现(源代码+LW)JAVA五子棋手机网络对战游戏的设计与实现(源代码+LW)JAVA五子棋手机网络对战游戏的设计与实现(源代码+LW)JAVA五子棋手机网络对战游戏的设计与实现(源代码+LW)

    人工智能+深度学习+卷积神经网络精细解读+整理版

    【项目资源】:汇聚了云计算、区块链、网络安全、前端设计、后端架构、UI/UX设计、游戏开发、移动应用开发、虚拟现实(VR)、增强现实(AR)、3D建模与渲染、云计算服务、网络安全工具等各类技术项目的素材和模板。包括AWS、Azure、Docker、Kubernetes、React、Vue、Angular、Node.js、Django、Flask、Unity、Unreal Engine、Blender、Sketch、Figma、Wireshark、Nmap等项目的素材和模板。【项目质量】:所有素材和模板都经过精心筛选和整理,确保满足专业标准。在发布前,我们已经对功能进行了全面测试,确保其稳定性和可用性。【适用人群】:适合对技术充满热情的初学者、希望提升专业技能的中级开发者、以及寻求创新解决方案的高级工程师。无论是个人项目、团队合作、课程设计还是商业应用,都能在这里找到合适的资源。【附加价值】:这些项目资源不仅具有很高的学习价值,而且能够直接应用于实际项目中,提高开发效率。对于有志于深入研究或拓展新领域的人来说,它们提供了丰富的灵感和基础框架,帮助你快速构建出令人惊艳的作品。

    node-v0.12.16-linux-x64.tar.xz

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

    node-v0.10.14-x86.msi

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

    Hnase课程-概念资料

    Hnase课程-概念资料

    太原理工软件工程Linux与Python编程

    太原理工软件工程Linux与Python编程实验报告,各位当个参考即可,不用过分较真,如果与你们想法不同,请以自己为主。

    springboot(火车站订票管理系统)

    开发语言:Java JDK版本:JDK1.8(或11) 服务器:tomcat 数据库:mysql 5.6/5.7(或8.0) 数据库工具:Navicat 开发软件:idea 依赖管理包:Maven 代码+数据库保证完整可用,可提供远程调试并指导运行服务(额外付费)~ 如果对系统的中的某些部分感到不合适可提供修改服务,比如题目、界面、功能等等... 声明: 1.项目已经调试过,完美运行 2.需要远程帮忙部署项目,需要额外付费 3.本项目有演示视频,如果需要观看,请联系我v:19306446185 4.调试过程中可帮忙安装IDEA,eclipse,MySQL,JDK,Tomcat等软件 重点: 需要其他Java源码联系我,更多源码任你选,你想要的源码我都有! https://img-blog.csdnimg.cn/direct/e73dc0ac8d27434b86d886db5a438c71.jpeg

    node-v0.10.2-x64.msi

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

    node-v0.11.13-x86.msi

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

    node-v0.10.43-linux-x86.tar.gz

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

    PiP-Tool-master.zip

    PiP-Tool-master

    雷池waf配置手册大全

    保姆式教学,手把手学习,让你清晰认识waf设备

    base.apk

    base.apk

    基于Java的雷电游戏的设计与实现

    电脑游戏,是指在计算机上能够运转的游戏软件。这种软件具有较强的娱乐性。电脑游戏的创新和发展与硬件、软件的发展紧密相关。它能够给玩家提供一个虚拟的环境,使游戏带给了人们很多的享受和欢乐。雷电游戏因为操作简单,节奏明快,一直是纵轴射击游戏的经典之作。经常能够在手机或者计算机中见到这款游戏,深得广大玩家的喜爱,可以说是妇孺皆知的一款益智类游戏。 本游戏基于Eclipse开发平台,以java作为编程语言,整个项目开发旨在模拟雷电游戏的飞机射击游戏。游戏界面的下部是玩家的飞机,可以根据按键控制子弹的发射,上部为敌方飞机,在界面中随机出现。在游戏过程当中,用户飞机的移动是被电脑键盘的方向键所控制的,在整个游戏过程当中,如果用户飞机的子弹与敌方飞机发生相撞时,敌方飞机就会有爆炸的效果产生。游戏中使用到的飞机、子弹均采用对应的类实现。

    基于FPGA的深度学习加速器的设计与实现

    【作品名称】:基于FPGA的深度学习加速器的设计与实现 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【项目介绍】:基于FPGA的深度学习加速器的设计与实现

    nodejs-ia32-0.11.6.tgz

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

Global site tag (gtag.js) - Google Analytics